Compiler: g++ 4.4.3 Boost...: 1.49.0 OS......: Ubuntu
注意:自从我认真使用C++已有15年了,所以我正在重新学习和学习新东西,因为我也尝试学习Boost.
给出以下代码:
1. class Beta {
2. public:
3. std::string name();
4. }
5.
6. class Alpha {
7. public:
8. Beta m_beta;
9. }
10.
11. Alpha one;
Run Code Online (Sandbox Code Playgroud)
由于各种原因,我想使用boost:bind来实现与调用"one.m_beta.name()"相同的结果.我认为以下会这样做:
12. boost::function<std::string(Alpha)>
13. b = boost::bind(
14. &Beta::name,
15. boost::bind(&Alpha::m_beta, _1)
16. );
17. cout << "NAME = " << b(one) << "\n";
Run Code Online (Sandbox Code Playgroud)
但是当我编译(在Ubuntu上的g ++ 4.4.3)时,我收到以下错误:
错误:从'const Beta*'无效转换为'Beta*'
在查看由第13-16行产生的实际类型定义之后,看起来第15行变为'const Beta*',但是包装它的绑定期望'Beta*'.
但是,这个DOES工作:
30. boost::function<std::string(Beta)>
31. p1 = boost::bind(&Beta::name,_1);
32. boost::function<Beta(Alpha)>
33. p2 = boost::bind(&Alpha::m_beta,_1);
34. std::cout << "NAME = " << p1(p2(one)) << "\n";
Run Code Online (Sandbox Code Playgroud)
但我真的不想携带很多中间变量.它确实让我觉得必须有一些方法让第一个版本也能运行.我已经尝试过以下作为第15行的替换,但是它们在编译时也会发出一个或另一个错误.
50. (boost::function<Beta&(Alpha)>)(boost::bind(&Alpha::m_beta,_1))
51. (boost::function<Beta(Alpha)>)(boost::bind(&Alpha::m_beta,_1))
52. (boost::function<Beta*(Alpha)>)(boost::bind(&Alpha::m_beta,_1))
53. boost::protect(boost::bind(&Alpha::m_beta,_1))
54. boost::ref(boost::bind(&Alpha::m_beta,_1))
55. const_cast<Beta*>(boost::bind(&Alpha::m_beta,_1))
56. const_cast<boost::function<Beta(Alpha) > >(boost::bind(&Alpha::m_beta,_1))
57. const_cast<boost::function<Beta*(Alpha) > >(boost::bind(&Alpha::m_beta,_1))
Run Code Online (Sandbox Code Playgroud)
我错过了什么?
显式指定Beta&嵌套的返回类型boost::bind:
boost::function< std::string( Alpha ) > b =
boost::bind(
&Beta::name,
boost::bind< Beta& >( &Alpha::m_beta, _1 ) );
Run Code Online (Sandbox Code Playgroud)
的原因const Beta*和Beta*转换错误发生是的结果boost::bind具有相同的行为boost::mem_fn,其中指出:
mem_fn还支持指向数据成员的指针,将它们视为不带参数的函数,并返回对成员的(const)引用
因此,嵌套绑定返回a const Beta&,这是一个无效的实例来调用非const name()成员函数Beta.