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

C++ 为什么我不能将函数中定义的函子传递给另一个函数?,c++,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)); r

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

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;
}
使用名称空间std;
int main(int argc,char*argv[])
{
结构MYINC{
int运算符()(int a){返回a+1;}
}myinc;
向量向量机;
对于(int i=0;i<10;i++)向量推回(myinc(i));
返回0;
}
但是,如果我将其传递给外部函数,如下面的示例中的std::transform,我会遇到一个编译错误,即
error:no匹配函数用于调用“transform(std::vector::iterator,std::vector::iterator,std::vector::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;
}
使用名称空间std;
int main(int argc,char*argv[])
{
结构MYINC{
int运算符()(int a){返回a+1;}
}myinc;
向量向量机;
对于(int i=0;i<10;i++)向量,向后推(i);
转换(vec.begin(),vec.end(),vec.begin(),myinc);
返回0;
}
所以我把定义放在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;
}
使用名称空间std;
结构MYINC{
int运算符()(int a){返回a+1;}
}myinc;
int main(int argc,char*argv[])
{
向量向量机;
对于(int i=0;i<10;i++)向量,向后推(i);
转换(vec.begin(),vec.end(),vec.begin(),myinc);
返回0;
}

<代码> > p>由于我不完全清楚的原因,C++ 03中有一个众所周知的、相当恼人的限制,您可以使用哪些类型来实例化模板。 本地定义的类不能用作模板的参数,原因是


顺便说一句,这使得很难恰当地使用
库,因为您无法将代码的上下文保持在本地,而是被迫将所有函子、比较器等放在命名空间级别,为它们编造有趣的名字,并将它们放在远离使用点的地方。

这两个版本都可以使用C++11编译器g++4.8.2进行良好编译

然而,C++03编译器在实例化具有本地类型的模板时会犹豫不决,因为在C++03中不支持这种类型

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

另一个解决方案是利用这一点,即使在C++03中,您也可以通过使其成为本地类的静态成员函数(在C++11中,您也可以通过使用lambda表达式)在本地定义“实”函数


然而,除了处理这样的问题外,函子比“实”函数具有一般性能优势,即使用类的对象而不是函数指针,并且使用相关的
操作符()
作为
内联
,编译器可以更好地优化,因为它知道函数的实现。

Re“本地定义的类不能用作模板的参数”,这在C++03中是如此,但在当前的标准C++11中已不再如此。Re“仅仅因为”,ut与本地类型没有链接这一事实相关联。但我并不比你更清楚为什么这是C++03中的一个sthowstepper。@cheers-sandhth.-Alf:修复了。很高兴知道C++11去掉了明显是无意义的限制。这是一个非常好而且有用的答案!如果知道C++11标准中该新功能在何处被定义为受支持,那就太好了。@DanNissenbaum;在C++98中(在C++03中未进行更正),在§14.3.1/2中规定“本地类型、无链接的类型、未命名类型或由这些类型中的任何一种组合而成的类型不得用作模板类型参数的模板参数”。在C++11中删除了此要求。因此,在C++11中,该功能不是“定义为受支持”,而是隐式指定为没有限制性要求,这很难引用。:-)我找到了。