[英]C++ variadic function template in std::functional
basically I want to integrate a multi-dimensional integral with this recursion.基本上我想将多维积分与此递归集成。
But the problem itself is a general one.但问题本身是一个普遍问题。 It's not specific for integration.
它不是特定于集成的。
#include "math.h"
#include <iostream>
#include <functional>
double f(double x,double y,double z){
return x+y+z+1;
}
//Base
double redDim(std::function<double(double)> &f){
return f(0); //a silly integrator for testing
}
// Recursion
template<typename Tfirst=double, typename... Trest>
auto redDim(std::function<double(Tfirst first,Trest... rest)> &f){
return redDim([=](Trest... R){return redDim([=](double x){return f(x,R...);});});
}
int main(){
std::cout<<redDim(f)<<std::endl;
return 0;
}
The problem is, compiler says:问题是,编译器说:
c:\C++\templateTutorial\templateTut.cpp: In function 'int main()':
c:\C++\templateTutorial\templateTut.cpp:24:19: error: no matching function for call to 'redDim(double (&)(double, double, double))'
cout<<redDim(f)<<endl;
^
c:\C++\templateTutorial\templateTut.cpp:12:8: note: candidate: 'double redDim(std::function<double(double)>&)'
double redDim(std::function<double(double)> &f){
^~~~~~
c:\C++\templateTutorial\templateTut.cpp:12:8: note: no known conversion for argument 1 from 'double(double, double, double)' to 'std::function<double(double)>&'
c:\C++\templateTutorial\templateTut.cpp:17:6: note: candidate: 'template<class Tfirst, class ... Trest> auto redDim(std::function<double(Tfirst, Trest ...)>&)'
auto redDim(std::function<double(Tfirst first,Trest... rest)> &f){
^~~~~~
c:\C++\templateTutorial\templateTut.cpp:17:6: note: template argument deduction/substitution failed:
c:\C++\templateTutorial\templateTut.cpp:24:19: note: mismatched types 'std::function<double(Tfirst, Trest ...)>' and 'double(double, double, double)'
cout<<redDim(f)<<endl;
^
The terminal process terminated with exit code: 1
So why is the type of f
not matching the requirements of redDim()
?那么为什么
f
的类型不符合redDim()
的要求呢?
Thus I can't even test, if my method works.因此,我什至无法测试,如果我的方法有效。
I hope you could help me!我希望你能帮助我!
A function pointer is not a std::function
.函数指针不是
std::function
。
Template argument deduction does not do any type conversions, other than a few to-base cases.模板参数推导不做任何类型转换,除了一些 to-base 情况。
Add a redim( double(*f)(Args...) )
template that calls the std function one.添加一个调用 std 函数 one 的
redim( double(*f)(Args...) )
模板。
template<class...Args>
auto redDim( double(*f)(Args...) {
return redDim( std::function<double(Args...)>{ f } );
}
and it should work.它应该工作。
This can deduce the signature of the function pointer.这可以推导出函数指针的签名。 It then explicitly converts to a
std::function
, which then matches your other redim
functions.然后它显式转换为
std::function
,然后匹配您的其他redim
函数。
You do have to explicitly convert your other lambdas to std::function
s:您必须将其他 lambda 显式转换为
std::function
:
// Recursion
template<typename Tfirst, typename... Trest>
auto redDim(std::function<double(Tfirst first,Trest... rest)> f){
return redDim(
std::function<double(Trest...)>{
[=](Trest... R){
return redDim(
std::function<double(double)>{
[=](double x){return f(x,R...);}
}
);
}
}
);
}
Also change the argument for the last redDim
to std::function<double(double)>
(not a reference). redDim
最后一个redDim
的参数更改为std::function<double(double)>
(不是参考)。 Alternatively, a const&
.或者,一个
const&
。
Based on Yakk - Adam Nevraumont's answer, the following code should compile:基于 Yakk - Adam Nevraumont 的回答,应该编译以下代码:
#include "math.h"
#include <iostream>
#include <functional>
double f(double x,double y,double z){
return x+y+z+1;
}
//Base
double redDim(const std::function<double(double)> &f){
return f(0); //a silly integrator for testing
}
// Recursion
template<typename Tfirst=double, typename... Trest>
auto redDim(const std::function<double(Tfirst first,Trest... rest)> &f) {
return redDim(
std::function<double(Trest...)>{
[=](Trest... R)->double{return redDim([=](double x){return f(x,R...);});}});
}
template<class...Args>
auto redDim( double(*f)(Args...)) {
return redDim( std::function<double(Args...)>{ f } );
}
int main(){
std::cout<<redDim(f)<<std::endl;
return 0;
}
As Yakk already pointed out, std::function
and a function pointer don't have the same type.正如 Yakk 已经指出的那样,
std::function
和函数指针没有相同的类型。 Please note that I've also changed the argument type of redDim
to const std::function<...> &)
.请注意,我还将
redDim
的参数类型redDim
为const std::function<...> &)
。 You could also pass rvalue
references using the &&
syntax.您还可以使用
&&
语法传递rvalue
引用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.