【发布时间】:2015-06-19 00:45:24
【问题描述】:
以下内容:
#include <functional>
struct Foo
{
void bar1() {}
void bar2(int) {}
void bar3(int, int) {}
void bar4(int, int, int) {}
};
int main()
{
Foo foo;
auto f1 = std::bind(&Foo::bar1, &foo);
auto f2 = std::bind(&Foo::bar2, &foo);
auto f3 = std::bind(&Foo::bar3, &foo);
auto f4 = std::bind(&Foo::bar4, &foo);
f1(1, 2, 3, 4); // success
f2(1, 2, 3); // error
f3(1, 2); // error
f4(1); // error
return 0;
}
f1(1, 2, 3, 4) 编译并执行 bar1()。 f2(1, 2, 3), 不编译, f3(1, 2) 不编译(但 bar3 有正确的原型), f4(1) 不编译。对于这 3 种情况,我使用 Visual Studio 2013 得到的错误是
“类没有定义一个 'operator()' 或用户定义的转换运算符到一个指向函数的指针或函数的引用,它接受适当数量的参数”
我对模板和标准库的了解有限,但这对我来说似乎没有任何逻辑意义。有合理的简单解释吗?
【问题讨论】:
-
您可能忘记在
f2、f3、f4中放置占位符(_1、_2、_3)。 @Matteo Italiabind有时比 lambda 更简洁。 -
好的,所以绑定到 bar1() 的 f1(1, 2, 3, 4) 不需要任何占位符。但是因为 operator() 不“检查” arity,所以 bar1() 被调用并且 (1, 2, 3, 4) 被模板魔法丢弃,没有错误。
-
void main 同样是错误的。
-
@sbabbi:我不认为(很少)更简洁的表示法可以证明更糟糕的语法和可怕的错误消息,只要你搞砸了。
boost::bind只是使 STL 的功能部分模糊地在 C++03 中可用的一种解决方法,我不明白为什么我们应该继续使用这样的组合,因为我们终于获得了核心语言级别的真实事物(lambdas,最重要的是闭包)。与std::auto_ptr和其他针对语言缺陷的解决方法一样,是时候忘记它曾经存在过。 -
如果没有类型擦除,您也无法将所有绑定结果存储在一个数组中。如果你使用
std::function,那么它与 lambdas 配合得很好。
标签: c++ std-function