c++ - 警告 : direct base class inaccessible in derived due to ambiguity; is this serious?

标签 c++ inheritance virtual ambiguity

我不明白这里有什么歧义。我确实确定了导致歧义的行并对其进行了标记。

#include <string>
#include <unordered_map>

class Spell {
    protected:
        struct Exemplar {};
        Spell() = default;
        Spell (Exemplar, const std::string&);
};

class SpellFromScroll : virtual public Spell {
    private:
        static std::unordered_map<std::string, SpellFromScroll*> prototypesMap;
    public:
        static void insertInPrototypesMap (const std::string& tag, SpellFromScroll* spell) {
            prototypesMap.emplace (tag, spell);
        }
        template <typename T> static SpellFromScroll* createFromSpell (T*);
};
std::unordered_map<std::string, SpellFromScroll*> SpellFromScroll::prototypesMap;

class SpellWithTargets : virtual public Spell {};  // *** Note: virtual

class Sleep : public SpellWithTargets {
    private:
        static const Sleep prototype;
    public:
        static std::string spellName() {return "Sleep";}
    private:
        Sleep (Exemplar e) : Spell (e, spellName()) {}
};
const Sleep Sleep::prototype (Exemplar{});

template <typename T>
class ScrollSpell : /*virtual*/ public T, public SpellFromScroll {};

Spell::Spell (Exemplar, const std::string& spellName) {
    // Ambiguity warning!
    SpellFromScroll::insertInPrototypesMap (spellName, SpellFromScroll::createFromSpell(this));
}

template <typename T>
SpellFromScroll* SpellFromScroll::createFromSpell (T*) {
    return new ScrollSpell<T>;
}

int main() {}

/*
c:\ADandD>g++ -std=c++14 Ambiguity.cpp -o a.exe -Wall -Wextra -pedantic-errors
Ambiguity.cpp: In instantiation of 'class ScrollSpell<Spell>':
Ambiguity.cpp:32:13:   required from 'static SpellFromScroll* SpellFromScroll::createFromSpell(T*) [with T = Spell]'
Ambiguity.cpp:27:90:   required from here
Ambiguity.cpp:23:7: warning: direct base 'Spell' inaccessible in 'ScrollSpell<Spell>' due to ambiguity
 class ScrollSpell : public T, public SpellFromScroll {};
       ^
Ambiguity.cpp:23:7: warning: virtual base 'Spell' inaccessible in 'ScrollSpell<Spell>' due to ambiguity [-Wextra]

c:\ADandD>
*/

它有多严重,随着程序的发展,以后会出现什么问题?

更新:找到一个解决方案,让 T 成为 ScrollSpell<T> 的虚拟基数. 但在我的程序中,T 始终是 Spell 的派生类,而 Spell 始终是 T 的虚基类。请参见下图。

                  Spell
                  /   \
              v  /     \ v
                /       \
               /         \  
   SpellFromScroll      SpellWithTargets
          \                \
           \                \
            \               Sleep
             \               /
              \             / v
               \           / 
             ScrollSpell<Sleep>

在上图中,为什么Sleep作为ScrollSpell<Sleep>的虚拟基地解决问题了吗?

最佳答案

template <typename T>
class ScrollSpell : public T, public SpellFromScroll {};

这里,T = Spell,所以 ScrollSpell 类将 Spell 类作为直接的非虚拟基类,并且通过 SpellFromScroll 作为虚拟基类。这就是歧义。将基类 T 声明为虚拟可能会解决问题。

此外,我并不真正理解设计背后的要点,因此这可能会引入一些全新的问题。

关于c++ - 警告 : direct base class inaccessible in derived due to ambiguity; is this serious?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30246098/

相关文章:

android - Google Play 游戏服务和 64 位 x86 支持

python - 配置字典中的继承

c++ - 如何知道ID2D1Brush是哪种画笔?

C++:虚拟指针的原型(prototype)

c++ - 为什么按值传递而不是按常量引用传递?

c++ - 将 const 数据传递给采用非常量而不使用 const_cast 的函数

C++ 继承和多态未知输出

C#:虚函数调用甚至比委托(delegate)调用更快?

operating-system - Linux 中的虚拟软盘驱动器

c++ - 多态调用3层析构函数