为什么我不能将函数中定义的函子传递给另一个函数?

Yan*_*Xie 5 c++

我发现仿函数可以用来模拟在这样的函数中定义一个函数

using namespace std;
int main(int argc, char* argv[])
{
    struct MYINC {
        int operator()(int a) { return a+1; }
    } myinc;
    vector<int> vec;
    for (int i = 0; i < 10; i++) vec.push_back(myinc(i));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我将它传递给外部函数,如std :: transform,如下例所示,我有一个编译错误说error: no matching function for call to ‘transform(std::vector<int>::iterator, std::vector<int>::iterator, std::vector<int>::iterator, main(int, char**)::MYINC&)’

using namespace std;
int main(int argc, char* argv[])
{
    struct MYINC{
        int operator()(int a) { return a+1; }
    } myinc;
    vector<int> vec;
    for (int i = 0; i < 10; i++) vec.push_back(i);
    transform(vec.begin(), vec.end(), vec.begin(), myinc);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

所以我把定义放在main函数之外,现在一切都好了.

using namespace std;
struct MYINC{
    int operator()(int a) { return a+1; }
} myinc;
int main(int argc, char* argv[])
{
    vector<int> vec;
    for (int i = 0; i < 10; i++) vec.push_back(i);
    transform(vec.begin(), vec.end(), vec.begin(), myinc);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Che*_*Alf 6

两个版本都可以使用g ++ 4.8.2编译,这是一个C++ 11编译器.

但是,C++ 03编译器不会实例化具有本地类型的模板,因为C++ 03不支持这种模板.

一个解决方案,如果这确实是问题的根本原因,那么就是使用更新的编译器版本或其他编译器.

另一个解决方案是利用它,即使在C++ 03中,你可以在本地定义一个"真正的"函数,使它成为本地类的静态成员函数(在C++ 11中,你也可以通过使用lambda表达式来实现) .

然而,除了处理这样的问题,该函子具有一般的性能优势在"真实"的功能,即一类,而不仅仅是一个函数指针的对象,并与有关operator()inline,编译器可以优化多更好,因为它知道函数实现.

  • @DanNissenbaum; 在C++ 98中(在C++ 03中没有更正),它在§14.3.1/ 2中指定"本地类型,没有链接的类型,未命名的类型或从这些类型中复合的类型不得用作模板类型参数的模板参数".在C++ 11中删除了此要求.因此,不是在C++ 11中"定义为受支持",而是将该能力隐含地指定为缺少限制要求,这很难引用.:-) (2认同)