【发布时间】:2013-07-23 12:18:36
【问题描述】:
有时我倾向于编写函子,不是为了维护函数调用之间的状态,而是因为我想捕获一些函数调用之间共享的参数。举个例子:
class SuperComplexAlgorithm
{
public:
SuperComplexAlgorithm( unsigned int x, unsigned int y, unsigned int z )
: x_( x ), y_( y ), z_( z )
{}
unsigned int operator()( unsigned int arg ) const /* yes, const! */
{
return x_ * arg * arg + y_ * arg + z_;
}
private:
// Lots of parameters are stored as member variables.
unsigned int x_, y_, z_;
};
// At the call site:
SuperComplexAlgorithm a( 3, 4, 5 );
for( unsigned int i = 0; i < 100; ++i )
do_stuff_with( a ); // or whatever
对比
unsigned int superComplexAlgorithm( unsigned int x, unsigned int y,
unsigned int z, unsigned int arg )
{
return x * arg * arg + y * arg + z;
}
// At the call site:
auto a = std::bind( superComplexAlgorithm, 3, 4, 5, std::placeholders::_1 );
for( unsigned int i = 0; i < 100; ++i )
do_stuff_with( a );
在我看来,第一个解决方案有很多缺点:
-
x、y、z所做工作的文档在不同的位置(构造函数、类定义、operator())进行拆分。 - 大量样板代码。
- 不太灵活。如果我想捕获不同的参数子集怎么办?
是的,我刚刚意识到 boost::bind 或 std::bind 有多么有用。现在,在我开始在我的很多代码中使用它之前,我的问题是:在任何情况下,我应该考虑在普通函数中使用手写无状态仿函数来绑定参数吗?
【问题讨论】:
-
最重要的是你应该考虑 lambdas
-
@stijn:我不想在调用现场定义
superComplexAlgorithm,因为它超级复杂,用在很多地方,需要测试和文档等。我不能看看 lambda 在这种情况下如何发挥作用,尽管我在其他情况下也经常使用它们。 -
@MarkusMayr,您可以用 lambda 替换
std::bind。你写的不是std::bind( superComplexAlgorithm, 3, 4, 5, std::placeholders::_1 ),而是[](int x) { return superComplexAlgorithm(3, 4, 5, x); }。 -
自从我可以使用 lambdas 以来,我没有使用过
bind或重载operator()一次。所以不,我无法想象这样的情况:) 将代码放入 lambda 或编写一个函数并从 lambda 调用它。 -
我想指出这个模式的“官方”名称是Currying。
标签: c++ c++11 boost-bind