我发现仿函数可以用来模拟在像这样的函数中定义一个函数
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 :: 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;
}
所以我把这个定义放在 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;
}
答案 0 :(得分:6)
两个版本都可以使用g ++ 4.8.2编译,这是一个C ++ 11编译器。
然而,C ++ 03编译器不会实例化具有本地类型的模板,因为在C ++ 03中不支持。
一个解决方案,如果这确实是问题的根本原因,那么就是使用更新的编译器版本或其他编译器。
另一种解决方案是利用它,即使在C ++ 03中,您也可以在本地定义“真实”函数,方法是将其作为本地类的 static 成员函数(在C ++ 11中也可以通过使用lambda表达式来实现。)
然而,除了处理这样的问题之外,仿函数与“真实”函数相比具有一般的性能优势,即具有类的对象而不仅仅是函数指针,以及相关的{{1}作为operator()
,编译器可以更好地优化,因为它知道函数实现。
答案 1 :(得分:1)
由于我不完全清楚的原因,在C ++ 03中有一个众所周知且非常恼人的限制,您可以使用它来实例化模板。
本地定义的类不能用作模板的参数,只是因为。
顺便说一下,对<algorithm>
库的使用非常困难,因为你无法将代码的上下文保持在本地,而是强制将所有函子,比较器等放在命名空间级别为他们制作有趣的名字,并将它们放在远离使用点的地方。