c++ - 将函数指针匹配为模板参数?
问题描述
我正在尝试使accumulate2
模板正常工作,但是会导致编译错误。我不确定为什么编译器无法将 lambda 函数与此模板匹配。有谁知道出了什么问题以及如何解决?谢谢
#include <iostream>
#include <algorithm>
using namespace std;
template<typename Iter, typename Val>
Val accumulate2(Iter first, Iter last, Val s, Val (*op)(Val&, Val&))
{
while (first!=last) {
s = op(s,*first);
++first;
}
return s;
}
template<typename Iter, typename Val, typename Oper>
Val accumulate(Iter first, Iter last, Val s, Oper op)
{
while (first!=last) {
s = op(s,*first);
++first;
}
return s;
}
int main(int argc, char *argv[])
{
int a[] = {1, 2};
int v0 = accumulate(a, a+2, 0, [](int _v0, int _v1){return _v0 + _v1;});
cout << v0 << endl;
int v1 = accumulate2(a, a+2, 0, [](int _v0, int _v1){return _v0 + _v1;});
cout << v1 << endl;
}
汇编:
clang++ -std=c++11 -pedantic -Wall test166.cc && ./a.out
test166.cc:30:14: error: no matching function for call to 'accumulate2'
int v1 = accumulate2(a, a+2, 0, [](int _v0, int _v1){return _v0 + _v1;});
^~~~~~~~~~~
test166.cc:6:5: note: candidate template ignored: could not match
'Val (*)(Val &, Val &)' against '(lambda at test166.cc:30:37)'
Val accumulate2(Iter first, Iter last, Val s, Val (*op)(Val&, Val&))
^
1 error generated.
解决方案
问题是函数签名需要删除引用,而 lambda 表达式需要是无状态的才能显式地成为函数指针。新的工作代码如下:
#include <iostream>
#include <algorithm>
using namespace std;
template<typename Iter, typename Val>
Val accumulate2(Iter first, Iter last, Val s, Val (*op)(Val, Val))
{
while (first!=last) {
s = op(s,*first);
++first;
}
return s;
}
template<typename Iter, typename Val, typename Oper>
Val accumulate(Iter first, Iter last, Val s, Oper op)
{
while (first!=last) {
s = op(s,*first);
++first;
}
return s;
}
int add(int a, int b)
{
return a + b;
}
int main(int argc, char *argv[])
{
int a[] = {1, 2};
int v0 = accumulate(a, a+2, 0, [](int _v0, int _v1){return _v0 + _v1;});
cout << v0 << endl;
int v1 = accumulate2(a, a+2, 0, &add);
cout << v1 << endl;
int v2 = accumulate2(a, a+2, 0, +[](int _v0, int _v1){return _v0 + _v1;});
cout << v2 << endl;
}
推荐阅读
- javascript - 为什么 req.body 返回一个空对象?
- c# - TaskContinuations 与异步 lambda 同步运行
- laravel - Laravel 5.7:是否可以在表中直接添加值?
- jmeter - 如何获取活动线程组中当前步骤的活动线程数?
- sql - 在会话监视器中的 SQL 文本查询以不同的方式设置
- asp.net-core - Partial 标签助手是否使用 RenderPartialAsync 或 PartialAsync
- adsutil.vbs - 嗨,我需要在 VBScript 上为 sysdm.cpl 发送键盘“TAB”
- c# - API 控制器 POST 方法 multipart/form-data 在主体内使用边界获取消息
- javascript - 数据表过滤器:点击单词并对表格中的值进行着色
- python - 如何从文件夹中读取所有图像并将同名图像保存在其他文件夹python中