【问题标题】:Diamond inheritance with boost::bind带有 boost::bind 的钻石继承
【发布时间】:2013-11-07 21:32:25
【问题描述】:

我有这样的设计:

template <class T>
class A
{
};

template <class T>
class B : public A<T> 
{
};

template <class T>
class C : public A<T> 
{
};

template <class T>
class D : public C<T>, public B<T> 
{
};

struct TConcrete {
int xyz;
};

class Concrete : public D<TConcrete>
{
void Foo();
};

void
Concrete::Foo()
{
Bar (boost::bind(&A::Afunc, this, _1, _2), boost::bind(&C::Cfunc, this, _1, _2),     boost::bind(&D::Dfunc, this, _1, _2));
}

编译器抱怨第一次 boost::bind 调用。 C 和 D 内部的函数调用没有问题。 这是确切的错误:

boost/bind/mem_fn_template.hpp(384) : 错误 C2594: 'newline' : 来自 'Concrete *' 的模棱两可的转换 到'一个 *' 和 [ T=T混凝土 ]

你有什么想法吗?

【问题讨论】:

  • 至少有一个公共继承应该是virtual public
  • 谢谢。需要开始修改高中概念。好久没接触c++了。
  • 通常情况下,对抽象类以外的任何事物(例如接口)使用多重继承表明您可能需要重新考虑您的设计。非抽象类的多重继承是最好的解决方案,这是非常罕见的

标签: c++ boost-bind diamond-problem


【解决方案1】:

您的继承图如下所示:

           Concrete 
              |
              D
             / \
            C   B
           /     \
          A       A

当您尝试将Concrete* 转换为A* 时,编译器不知道您想要哪个A 实例。您想转换为C 派生自的A,还是B 派生自的A

解决方法是使用虚拟继承从A派生BC,这样A的实例就只有一个。

           Concrete 
              |
              D
             / \
            C   B
             \ /
              A

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 2013-05-16
    • 2020-10-03
    • 1970-01-01
    • 2022-01-12
    • 2020-01-01
    相关资源
    最近更新 更多