double boost :: bind导致编译时错误

时间:2012-04-11 19:38:51

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

以下代码给出了第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&lt; void()&gt;”,那么如何使boost :: bind返回这样的类型?

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

3 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:0)

查看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进行编译。

答案 2 :(得分:0)

我没有使用bind的经验,但是你通常不需要你正在调用成员函数的类的实例吗?如果未将其包含在绑定中,则需要将其包含在调用站点中。使用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%肯定(没有编译它),但根据提升网站上的文档(提升bind doc,提升mem_fn doc)这是我认为正在发生的事情。

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

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