【问题标题】:Why is "boost::function = boost::bind(...)" creating 13 temporaries?为什么“boost::function = boost::bind(...)”会创建 13 个临时对象?
【发布时间】:2013-01-15 02:02:46
【问题描述】:

我有一些非常基本的测试代码。我有一个只记录所有操作的类。我将它绑定到boost::function 对象,如下所示:

    void Function(const Foo&)
    {
        printf("Function invoked\n");
    }

    // ...

    boost::function<void(void)> func;
    {
        Foo f;
        printf("\nConstructing function\n");
        func = boost::bind(&Function, f);
        printf("Construction complete\n\n");
    }

我希望函数对象包含f 的副本。因此,必须创建至少一个副本。但是,我发现我得到了 13 个临时工。输出是:

Constructing function
Foo::Foo(const Foo&)
Foo::Foo(const Foo&)
Foo::Foo(const Foo&)
Foo::Foo(const Foo&)
Foo::~Foo
Foo::Foo(const Foo&)
Foo::~Foo
Foo::~Foo
Foo::Foo(const Foo&)
Foo::Foo(const Foo&)
Foo::Foo(const Foo&)
Foo::Foo(const Foo&)
Foo::Foo(const Foo&)
Foo::Foo(const Foo&)
Foo::Foo(const Foo&)
Foo::~Foo
Foo::~Foo
Foo::~Foo
Foo::~Foo
Foo::~Foo
Foo::Foo(const Foo&)
Foo::~Foo
Foo::Foo(const Foo&)
Foo::~Foo
Foo::~Foo
Foo::~Foo
Foo::~Foo
Construction complete

我不能使用refcref,因为我确实需要它来制作对象的副本。我做错了什么可怕的事情吗?或者我是否需要使用包装器(如boost::shared_ptr)来避免数量过多的副本?

完整代码和问题演示可以在on Codepad找到。

【问题讨论】:

  • 我很想看看 std::bind 做了什么。
  • 这是在调试还是发布?
  • @NicolBolas 仅使用g++ 进行编译,除了-O2 之外没有特殊标志或选项。尝试使用和不使用 c++11,没有区别。
  • @chris:使用std::functionstd::bind,只会创建two temporaries
  • 我怀疑 boost::bind 没有升级到 C++11。

标签: c++ boost-bind boost-function


【解决方案1】:

如果您删除“func =”分配部分,副本数会降低到 4 个,这比 13 个要好。

template <class F>
void callF(F fun)
{
}
callF(boost::bind(&func, fl));

所以解决方案很简单——不要使用 boost::function

【讨论】:

  • boost::thread(boost::bind(&amp;Function, q)); 给了我 7 个临时对象。
  • i.post(boost::bind(&amp;Function, q)); 提供 6 个临时对象。
  • 嗯,是的,在这种情况下,如果您发布的对象不够小而无法通过值更快地传递,或者您不需要太多对象,我认为您考虑使用 shared_ptr 是正确的.测试性能。
  • 我认为你是对的,解决方案是尽可能避免boost::function。如果不能,请了解成本。 (或者去c++11x)
猜你喜欢
  • 2016-03-16
  • 1970-01-01
  • 2011-01-11
  • 1970-01-01
  • 1970-01-01
  • 2012-02-17
  • 1970-01-01
  • 2012-04-18
  • 1970-01-01
相关资源
最近更新 更多