【问题标题】:double boost::bind cause compile-time errordouble boost::bind 导致编译时错误
【发布时间】:2012-04-11 19:38:51
【问题描述】:

以下代码给出了第 17 行导致的编译错误:

#include <boost/bind.hpp>
#include <boost/function.hpp>

void func()
{}

class A{
public:

    template <typename T>
    static void foo(T const& arg){}

    template <typename T>
    void bar(T const& arg){
        boost::bind(&A::foo<T>, arg);  //OK
        boost::function<T> functor1 = boost::bind(func); //OK
        boost::function<T> functor2 = boost::bind(&A::foo<T>, arg); //ERROR, LINE 17
    }
};

int main()
{
    A obj1;
    obj1.bar(func);
}

问题是,第 17 行的 functor2 原型应该是什么?
如果我真的想保持functor2的原型为“boost::function,如何让boost::bind返回这样的类型?

编译错误为:usr/include/boost/bind/bind.hpp:253: error: invalid initialization of reference of type 'void (&amp;)()' from expression of type 'void (*)()'
什么意思?

【问题讨论】:

  • 试试 boost::function functor2 = boost::bind(&A::foo, arg);
  • 那行不通。因为 T 已经是“void(*)()”了。

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


【解决方案1】:

foo(T const&amp; arg) 接受引用参数。为了通过boost::bind 传递引用参数,您需要用boost::ref 包装它。

boost::function<T> functor2 = boost::bind(&A::foo<T>, boost::ref(arg));

【讨论】:

    【解决方案2】:

    看看What is the return type of boost::bind?

    简而言之,我会写

    auto functor2 = boost::bind(&A::foo<T>, arg);
    

    并使用 gcc 4.6+ 或带有 --std=gnu++0x 选项的 gcc 4.4 编译它。

    【讨论】:

    • 很遗憾,我无法打开 cpp0x 选项。上面的示例代码是从实际项目代码中简化和最小化的。构建线束已修复,不能使用新标准。
    【解决方案3】:

    我对绑定没有经验,但是您通常不需要调用成员函数的类的实例吗?如果您不将其包含在绑定中,则需要将其包含在调用站点中。在我的示例中使用auto(我在上面阅读过您不能使用它,但为了简洁起见,我会使用它),我将重新实现您的 A::bar() 方法:

    void bar(T const& arg){
        auto barebones = boost::bind(&A::foo<T>, arg);
        // OR
        auto barebones = boost::bind(&A::foo<T>, _1, arg);
        barebones(this); // Need an instance, or a pointer to an instance of A
        boost::function<T> functor1 = boost::bind(func); // OK because func is a bare function with no arguments
        boost::function<T> functor2 = boost::bind(&A::foo<T>, this, arg); // betting that would work
        functor2(); // with my modification, I think that'll work.
    }
    

    你可能需要 _1 语法来说明第一个参数占据那个位置,或者没有它也可以工作。我不是 100% 确定(还没有编译它),但是根据 boost 站点上的文档(boost bind doc,boost mem_fn doc),我认为这是正在发生的事情。

    为什么要编译第一部分,我不知道。这让我怀疑原来的语法没问题,但是你需要传递类实例。如果您正在寻找不需要额外参数的“裸”可调用对象,则需要在绑定时传递一个实例(或指向一个的指针,或指向一个的智能指针)。

    如果您在推断类型时遇到问题,请尽可能尝试使用 BOOST_AUTO() 宏。 Doc link.

    【讨论】:

      猜你喜欢
      • 2012-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-12
      • 1970-01-01
      • 2020-03-26
      • 2023-03-25
      • 1970-01-01
      相关资源
      最近更新 更多