双加速::绑定导致编译时错误

double boost::bind cause compile-time error

本文关键字:编译时错误 绑定 加速      更新时间:2023-10-16

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

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

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

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

看看 boost::bind 的返回类型是什么?

简而言之,我只会写

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

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

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

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

如果您在推断类型时遇到问题,请尽可能尝试使用 BOOST_AUTO() 宏。 文档链接。