4
编译器:g++ 4.4.3
提升...:1.49.0
操作系统……: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;

由于各种原因,我想使用 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";

但是当我编译(Ubuntu 上的 g++ 4.4.3)时,出现以下错误:

错误:从 'const Beta*' 到 'Beta*' 的无效转换</blockquote>

在查看了从第 13-16 行得到的实际类型定义之后,看起来第 15 行正在变成“const Beta*”,但它的绑定包装需要“Beta*”。

但是,这确实有效:

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";

但是我真的不想携带很多中间变量。它确实让我认为必须有某种方法让第一个版本也能正常工作。我已经尝试过以下作为第 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))

我错过了什么?

4

1 回答 1

5

显式指定Beta&嵌套的返回类型boost::bind

boost::function< std::string( Alpha ) > b =
  boost::bind(
    &Beta::name,
    boost::bind< Beta& >( &Alpha::m_beta, _1 ) );

const Beta*发生和Beta*转换错误的原因是boost::bind具有与 相同的行为boost::mem_fn,其中指出:

mem_fn还支持指向数据成员的指针,将它们视为不带参数的函数并返回对成员的(const)引用。`

因此,nested-bind 将返回 a const Beta&,这是一个无效的实例,无法调用name()on 的非常量成员函数Beta

于 2012-08-18T03:19:54.560 回答