首页 > 解决方案 > 将函数指针匹配为模板参数?

问题描述

我正在尝试使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.

标签: c++c++11

解决方案


问题是函数签名需要删除引用,而 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;
}

推荐阅读