我试图建立一个基本但通用的渐变生成函数。目标是使函数gradient
获取函数和可变参数,并在提供的点返回复数值的向量。代码如下:
grad.h
#include <complex>
#include <vector>
/**base case*/
template<typename FNC, typename T>
auto gradientHelper(FNC&& fnc, std::vector<T>&& val){
return std::move(val);
}
/**recursive case*/
template<typename FNC, typename T, typename...Ts>
auto gradientHelper(const FNC& fnc, std::vector<T>&& val, const T& current, const Ts&... others){
val.emplace_back(fnc(std::complex<T>(current, 1.0), others...).imag());
return gradientHelper(
[&](const Ts&... others){
return fnc(current, others...);
}, std::move(val), others...);
}
/**calling case*/
template<typename FNC, typename T, typename...Ts>
auto gradient(FNC&& fnc, const T& param, const Ts&... params){
return gradientHelper(fnc, std::vector<T>(), param, params...);
}
main.cpp
#include "grad.h"
#include <vector>
int main(){
auto myTestFunc=[](const auto& x, const auto& y){
return x*y;//gradient should be [y, x]
};
double testX=2;
double testY=3;
std::vector<double> answer({testY, testX});
gradient(myTestFunc, testX, testY);
}
使用g++ -std=c++14 -O3 main.cpp
我收到以下错误:no known conversion for argument 1 from ‘std::complex<double>’ to ‘const double&’
我明白为什么会收到此错误。我已经使用参数类型gradient
实例化了传递到complex, double
的函数,然后使用参数类型double, complex
再次调用它。我的问题是如何解决这个限制。我对变参数或SFINAE编码没有多少经验,而且我曾用过的资源并未指向正确的方向。任何帮助将不胜感激!
编辑:使代码没有依赖项,除了标准库。
Edit2:制作最小,完整且可验证的示例。
答案 0 :(得分:0)
我通过更改代码解决了这个问题:
template<typename FNC, typename T, typename...Ts>
auto gradientHelper(const FNC& fnc, std::vector<T>&& val, const T& current, const Ts&... others){
val.emplace_back(fnc(std::complex<T>(current, 1.0), others...).imag());
return gradientHelper(
/*This won't work! The template is already defined!*/
/*[&](const Ts&... others){
return fnc(current, others...);*/
/*This will work! The remaining parameters
are deduced on the next call*/
[&](const auto&... remaining){
return fnc(current, remaining...);
}
}, std::move(val), others...);
}