2016-04-25 6 views
1

Предположим, у меня есть:Как я должен обрабатывать конфликт с множественным наследованием типов, а не методов?

class A { public: using foo_t = int; } 
class B { public: using foo_t = int; } 
class C : public A, public B { } 

Я хочу обратиться к C::foo_t. Да, это должно быть C::foo_t, а не C::A::foo_t или C::B::foo_t. Очевидно, компилятор жалуется на двусмысленность. Если бы это были методы, я мог бы использовать виртуальное наследование и, возможно, mixin, чтобы сформировать алмаз, а что - нет. Но что мне делать для типов? Должен ли я просто вручную добавить инструкцию?

Примечание:

  • Вы можете предположить, что я статический утверждать оба foo_t являются одинаковыми.
+0

Почему не 'с помощью foo_t = A :: foo_t'? – skypjack

+2

Где ваше наследование бриллиантов? Я могу видеть только множественное наследование, C наследуется от A и B. – Janosimas

+1

[Наследование бриллиантов] (https://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem) возможно только по меньшей мере с 4 классами. – Drop

ответ

4

Используя утверждение достаточно действительно:

class A { public: using foo_t = int; }; 
class B { public: using foo_t = int; }; 
class C : public A, public B { public: using A::foo_t; }; 

int main() { 
    C::foo_t v = 0; 
} 

Таким образом, C::foo_t определенно A::foo_t (как правильно предложено в комментариях).
Если вы хотите определить foo_t типа или нового типа для C вместо этого, вы можете сделать это, как это следующим образом:

class C : public A, public B { public: using bar_t = A::foo_t; }; 

Вот минимальный, полный пример, где типы проверяются, чтобы быть таким же, используя SFINAE вместо статического утверждения:

#include<type_traits> 

class A { public: using foo_t = int; }; 
class B { public: using foo_t = int; }; 
class C { public: using foo_t = double; }; 

template<class T, class U, 
    std::enable_if_t<std::is_same<typename T::foo_t, typename U::foo_t>::value>* = nullptr> 
class D: public T, public U { public: using T::foo_t; }; 

int main() { 
    D<A, B>::foo_t v = 0; 
    // the line below does not compile 
    //D<A, C>::foo_t v = 0; 
} 
+0

Добавлены аксессоры. – einpoklum

+0

Я знаю, что этого достаточно, но верно ли это (ТМ)? – einpoklum

+0

Вы хотите, чтобы 'C' выставлял тип. Какой тип? Это разумный способ определить его, и, конечно же, это * правильный. – skypjack