【问题标题】:Why boost::bind incompatible with forward declaration?为什么 boost::bind 与前向声明不兼容?
【发布时间】:2015-11-12 08:43:20
【问题描述】:

boost::bind 无法绑定通过前向声明声明的参数。

谁能解释为什么?这是一个提升错误吗?

示例代码:

#include "boost/function.hpp" 
#include "boost/bind.hpp" 
#include <vector>
#include <iostream>

class B;
class A
{
public:
    A() {}

    void func1(int i)                      { std::cout << __PRETTY_FUNCTION__ << "(" << i << ")\n"; } 
    void func2(const std::string& s)       { std::cout << __PRETTY_FUNCTION__ << "(" << s << ")\n"; }
    void func3(const B& b)       { std::cout << __PRETTY_FUNCTION__ << "(" << "unknown" << ")\n"; } 

    static void dispatch(      std::vector<A>& vect, boost::function<void(A      &)> const& func)
    {
        for ( std::vector<A>::iterator iter = vect.begin();
              iter != vect.end();
              ++iter )
        {
            func(*iter);
        }
    }
};

int main()
{
    std::vector<A> vect(3);

    A::dispatch(vect, boost::bind(&A::func1, _1, 3));
    A::dispatch(vect, boost::bind(&A::func2, _1, "hello"));

    const B* b = NULL;
    A a;
    a.func3( *b ); // compiles and works!!
    A::dispatch(vect, boost::bind(&A::func3, _1, *b)); // does not compile!!
}

报告的错误是:

main.cpp:37:52: error: invalid use of incomplete type 'class B'
     A::dispatch(vect, boost::bind(&A::func3, _1, *b)); // does not compile

现场演示:http://coliru.stacked-crooked.com/a/5f9437627fdf3c53

【问题讨论】:

    标签: c++ boost boost-bind


    【解决方案1】:

    那是因为 bind 按值存储了绑定的参数。

    如果您不想这样做,请将它们包装在参考包装器中:boost::ref(x)boost::cref(x)

    A::dispatch(vect, boost::bind(&A::func3, _1, boost::cref(*b))); 
    

    编译:

    Live On Coliru

    #include "boost/function.hpp" 
    #include "boost/bind.hpp" 
    #include <vector>
    #include <iostream>
    
    class B;
    class A
    {
    public:
        A() {}
    
        void func1(int i)                      { std::cout << __PRETTY_FUNCTION__ << "(" << i << ")\n"; } 
        void func2(const std::string& s)       { std::cout << __PRETTY_FUNCTION__ << "(" << s << ")\n"; }
        void func3(const B& b)       { std::cout << __PRETTY_FUNCTION__ << "(" << "unknown" << ")\n"; } 
    
        static void dispatch(      std::vector<A>& vect, boost::function<void(A      &)> const& func)
        {
            for ( std::vector<A>::iterator iter = vect.begin();
                  iter != vect.end();
                  ++iter )
            {
                func(*iter);
            }
        }
    };
    
    int main()
    {
        std::vector<A> vect(3);
    
        A::dispatch(vect, boost::bind(&A::func1, _1, 3));
        A::dispatch(vect, boost::bind(&A::func2, _1, "hello"));
    
        const B* b = NULL;
        A a;
        a.func3( *b ); // compiles and works!!
        A::dispatch(vect, boost::bind(&A::func3, _1, boost::cref(*b))); 
    }
    

    【讨论】:

    • 你的意思是如果没有boost::cref,我实际上是在加速没有副本可以完成?
    • 不能代表你的期望,但是,这正是我在第一句话中所说的:)
    • 这在某些情况下不会有风险吗?
    • 是的,它不能。复制从来没有风险。持有参考文献的风险要大得多(副本没有终身问题,即它们不会变得悬空)。欢迎使用 C++,这是一种 value-semantics-by-default 的语言
    • 知道了 ;-)。再次感谢您的帮助
    猜你喜欢
    • 2012-12-02
    • 1970-01-01
    • 2013-05-02
    • 1970-01-01
    • 2012-02-13
    • 2015-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-11
    相关资源
    最近更新 更多