c++11 - 将带有模板参数的仿函数传递给模板函数
问题描述
我正在编写一个以仿函数为参数的函数。仿函数的调用运算符的参数是模板化的。我正在尝试做的一个非常简化的版本是:
#include <iostream>
#include <functional>
#include <array>
template <const size_t N>
using CVec = std::array<double,N>;
template<const size_t N>
using ode_fun = std::function<CVec<N>(const CVec<N>&)>;
template<const size_t N>
void step( const CVec<N>& x, ode_fun<N> sys)
{
sys(x);
}
struct foo_t
{
CVec<2> operator()( const CVec<2>& x_in)
{
CVec<2> xdot;
std::cout << "x_in: [" << x_in[0] << ", " << x_in[1] << "]\n";
return xdot;
}
CVec<2> x;
};
int main()
{
foo_t foo;
foo.x[0] = -.5;
foo.x[1] = 1.0f;
CVec<2> x;
x[0] = 12.0;
x[1] = 23.2;
step(x, foo);
}
但是在编译时,我收到此错误:
temp_arg_subs_fail.cpp: In function ‘int main()’:
temp_arg_subs_fail.cpp:42:14: error: no matching function for call to ‘step(CVec<2>&, foo_t&)’
step(x, foo);
^
temp_arg_subs_fail.cpp:12:6: note: candidate: template<long unsigned int N> void step(CVec<N>&, ode_fun<N>)
void step( const CVec<N>& x, ode_fun<N> sys)
^~~~
temp_arg_subs_fail.cpp:12:6: note: template argument deduction/substitution failed:
temp_arg_subs_fail.cpp:42:14: note: ‘foo_t’ is not derived from ‘std::function<std::array<double, N>(const std::array<double, N>&)>’
step(x, foo);
^
但是,这有效:
#include <functional>
#include <iostream>
using my_fn = std::function<int(int, int)>;
void summer(int x, int y, my_fn fn)
{
std::cout << "summer: " << fn(x,y) << std::endl;
}
struct foo_t
{
int operator()(int x, int y)
{
return x + y + z;
}
int z = 0;
};
int main ()
{
foo_t foo;
foo.z = 5;
summer(3,4,foo);
return 0;
}
基本上,我能看出两者之间的唯一区别是一个是模板化的,另一个不是。是因为第一个片段中的 step 函数只是一个模板而不是实例化还是其他什么?
解决方案
问题是step()
需要一个ode_fun<N>
对象作为第二个参数(即 a std::function<std::array<double, N>(std::array<double, N> const &)>
)并且N
要被推导。
但是,如果您通过foo
,那是一个foo_t
可以转换为的对象,但是ode_fun<2>
(这就是重点)不是ode_fun<2>
对象,编译器就无法推断出该N
值。
您可以通过两种明显的方式解决问题。
(1) 传递一个ode_fun<2>
对象step()
ode_fun<2> foo2 { foo };
step(x, foo2);
(2) 或在 中推导出一个简单类型F
(如“泛函”)step()
,因此所有泛函都是可推导的
template<const size_t N, typename F>
void step( const CVec<N>& x, F sys)
{
sys(x);
}
是因为第一个片段中的 step 函数只是一个模板而不是实例化还是其他什么?
确切地。
在您的非模板示例中,summer()
接收一个std::function<int(int, int)>
.
没有什么可以推导出来的,将一个foo_t
不是 astd::function<int(int, int)>
但可以转换为它的对象传递给它,编译器转换foo
为std::function<int(int, int)>
.
推荐阅读
- powershell - 新的 PowerShell 代码未执行 | 视觉工作室代码
- python - Postgresql - Pgadmin:将 json 文件插入表中
- unity3d - unity AudioSource.Play 有噪音
- c# - 如何在对 Application Insights 友好的 Web API 中处理异常
- java - 安装 WAR 后,IBM WAS 9 在前 2 次调用特定方法时出错,然后在第 3 次调用和所有下一次调用中运行良好
- python - ConfigArgParse 忽略缩写选项?
- .net - .net RichTextBox - 自动设置字体
- ruby-on-rails - Activerecord rails 中的子查询
- angular - Angular Kendo UI Grid 使用 Detail Grid 递归加载
- node.js - 无法在 Windows 10 上安装 @vue/cli 3