以下传递函数对象的小程序出了什么问题?
#include <iostream>
#include <functional>
void foo(const std::unary_function<const std::string&, void>& fct) {
const std::string str = "test";
fct(str); // error
}
class MyFct : public std::unary_function<const std::string&, void> {
public:
void operator()(const std::string& str) const {
std::cout << str << std::endl;
}
};
int main(int argc, char** argv){
MyFct f;
foo(f);
return 0;
}
我在第6行收到以下错误:
no match for call to
`(const std::unary_function<const std::string&, void>) (const std::string&)'
答案 0 :(得分:11)
一个常见的错误。 unary_function
和binary_function
只是两个添加typedef
argument_type
result_type
和
first_argument_type
second_argument_type
result_type
不多了。它们是为了方便函数对象类型的创建者,因此它们不必自己执行。但他们并不表现出多态性。你想要的是功能对象包装器。想到boost::function
:
void foo(boost::function<void(const std::string&)> const& fct) {
const std::string str = "test";
fct(str); // no error anymore
}
或将其设为模板
template<typename FunctionObject>
void foo(FunctionObject const& fct) {
const std::string str = "test";
fct(str); // no error anymore
}
您可以按值获取,然后从foo
返回副本,如果使用它将其应用于某个序列。这将允许函数对象更新其成员中的某些状态变量。 for_each
就是这样做的一个例子。一般来说,无论如何,我会接受它们的价值,因为它们通常很小,复制它们可以提供更大的灵活性。所以我做了
template<typename FunctionObject>
void foo(FunctionObject fct) {
const std::string str = "test";
fct(str); // no error anymore
}
然后你可以获取fct的副本并将其保存在某个地方,fct
的operator()可以是非const并更新一些成员(这是{{1}的一部分。 1}})。请记住,如果通过const引用获取函数对象,则通常无法复制它,因为用户可能已经传递了一个函数。然后复制它将尝试本地声明一个函数而不是本地函数指针。但是,接受by-value会在函数传递时接受函数指针,这可以安全地复制。