2017-08-24 18 views
0

我很長時間在使用此可變參數模板。任何人都可以幫助我嗎?我想建立一個能夠調用cmath函數並通過向量傳遞其所有參數的執行程序。請考慮下面的代碼:在向量中傳遞參數的函數執行程序中的C++歧義

bool execute(const std::string &functionName, const std::vector<double> &params) 
{ 
    if (functionName == "cos") return execute(cos, params); 
    if (functionName == "atan2") return execute(atan2, params); 
    return false; 
} 

功能cos需要一個參數,而atan2有兩個。我想有這樣的事情:

template <typename... Types> 
bool execute(double (*func)(Types...), const std::vector<double> &params) 
{ 
    if (params.size() != sizeof...(Types)) { 
     errorString = "Wrong number of function arguments"; 
     return false; 
    } 

    errno = 0; 
    result = func(params[0]); 
    errorString = strerror(errno); 
    return !errno; 
} 

不過,我遇到了兩個問題:

  1. 功能cos作品都doublefloat,所以調用是不明確的。此外,我不能用double代替typename來強制它。或者有其他方法?
  2. 當我試圖調用函數func如何根據函數類型從矢量指定正確數量的參數?

或者,也許有什麼已經在C++中可用,我不知道? :) 非常感謝!

+1

既然你顯然只需要一個和兩個參數來處理功能,這將是最容易寫兩個非模板重載,一個以'雙(* FUNC)(雙)'和其他'雙( * func)(雙,雙)' –

+0

@IgorTandetnik,謝謝。這就是我現在正在做的事情。我只是想減少模板的代碼量。但是我不知道它是否有可能。 –

+0

這是可能的,但我不認爲它實際上會減少代碼量。它肯定會讓它變得更加複雜。 –

回答

1

您可以使用std::index_sequence,像:

template <typename... Types, std::size_t ... Is> 
double execute(double (*func)(Types...), 
       const std::vector<double> &params, 
       std::index_sequence<Is...>) 
{ 
    if (params.size() != sizeof...(Types)) { 
     throw std::runtime_error("Wrong number of function arguments"); 
    } 
    return func(params[Is]...); 
} 

template <typename... Types> 
double execute(double (*func)(Types...), const std::vector<double> &params) 
{ 
    return execute(func, params, std::index_sequence_for<Types...>()); 
} 

,並呼籲它(指定模板參數來解決過載)。

double execute(const std::string &functionName, const std::vector<double> &params) 
{ 
    if (functionName == "cos") return (execute<double>)(cos, params); 
    if (functionName == "atan2") return (execute<double, double>)(atan2, params); 
    throw std::runtime_error("Unknown function name"); 
} 
相關問題