2015-11-12 67 views
1

boost::bind無法綁定通過前向聲明聲明的參數。爲什麼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

回答

4

這是因爲綁定存儲綁定參數通過值

如果您不想要,請將它們包裝在引用包裝中: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))); 
} 
+0

你的意思是,如果沒有'的boost :: cref'的時候我其實是expeting沒有副本做副本做了什麼? – jpo38

+0

不能說你的期望,但是,這正是我在第一句話中所說的:) – sehe

+0

在某些情況下,這不會有風險嗎? – jpo38