我需要使用参数延迟调用某些函数。有下一个测试代码:
#include <functional>
#include <boost/bind.hpp>
#include <boost/function.hpp>
struct test
{
test()
{
std::cout << "ctor" << std::endl;
}
test& operator=(test const& t)
{
std::cout << "operator=" << std::endl;
return *this;
}
test(test const& t)
{
std::cout << "copy ctor" << std::endl;
}
~test()
{
std::cout << "dtor" << std::endl;
}
};
int foo(test const & t)
{
return 0;
}
int main()
{
test t;
boost::function<int()> f = boost::bind(foo, t);
f();
return 0;
}
输出是:
ctor
copy ctor
copy ctor
copy ctor
copy ctor
dtor
copy ctor
dtor
dtor
copy ctor
copy ctor
copy ctor
copy ctor
copy ctor
copy ctor
dtor
dtor
dtor
dtor
dtor
dtor
dtor
dtor
dtor
所以我们可以看到ctor的副本叫了11次!!!
确定。将boost :: bind更改为std :: bind:
int main()
{
test t;
boost::function<int()> f = std::bind(foo, t);
f();
return 0;
}
输出是:
ctor
copy ctor
copy ctor
copy ctor
dtor
copy ctor
copy ctor
copy ctor
copy ctor
copy ctor
copy ctor
dtor
dtor
dtor
dtor
dtor
dtor
dtor
dtor
dtor
复制ctor 9次。好。如果将boost :: function更改为std :: function copy ctor将仅被调用4次。但这也是不好的行为。
是否可以通过1次复制ctor来执行此操作? std :: ref是个坏主意,因为它可以在其他线程等中调用。
抱歉我的英文不好:)谢谢。
答案 0 :(得分:1)
使用lambda表达式。
int main()
{
test t;
std::function<int()> f = [=](){ foo(t); };
f();
return 0;
}
由于使用lambdas的难易程度等原因,绑定非常多余。此外,您在发布模式下进行了所有优化的编译,对吧?
您不会只获得一个复制构造函数调用,因为首先必须生成一个函数对象,然后将该函数对象分配给std :: function。也许它可能是std::move
'd?
由于你没有lambdas甚至绑定产生三个副本,在这种情况下你只需要手动编写自己的函数对象。
答案 1 :(得分:1)
使用lambdas是一个很好的答案。如果由于任何不适合你的原因,另一种可能性是将绑定的结果存储在除std :: function之外的其他内容中:
decltype(std::bind(foo, t)) f = std::bind(foo, t);
或:
auto f = std::bind(foo, t);
在我的系统(clang / libc ++)上输出:
ctor
copy ctor
dtor
dtor
虽然你的milage可能会有所不同。
答案 2 :(得分:0)
它确实依赖于您要绑定的对象的生命周期。
假设该对象的生命周期包括仿函数的生命周期,只需执行
int main()
{
test t;
boost::function<int()> f( boost::bind(foo, boost::ref( t ) ) );
f();
return 0;
}
产生一个构造函数调用和一个析构函数调用。 : - )
干杯&amp;第h。,