Конструктор инициализации шаблонного базового класса завершается неудачно, несмотря на точное совпадение имени класса C ++ - PullRequest
0 голосов
/ 01 ноября 2011

В следующем коде у меня есть элемент в списке инициализатора

ExtendHelper<Extender>::Type<>

, который точно соответствует базовому классу:

ExtendHelper<Extender>::Type<>

Но компилятор VS2010 жалуется: error C2614: 'Base::Type<T>::Extend<Extender>' : illegal member initialization: 'Type<Base::Type<Base::Type<Base>::ExtendHelper<Data> >::ExtendHelper<Data> >' is not a base or member,

Как это может быть?

struct Base
{
    template <class T=Base>
    struct Type
    {
        template <class Extender>
        struct ExtendHelper
        {
            template <class U=ExtendHelper>
            struct Type
                :
                T::Type<U>,
                Extender
            {
                Type(typename T::Type<T> &rhs) 
                    :
                    T::Type<U>(rhs)
                {
                }
                Type() {}
            };
        };

        template <class Extender>
        struct Extend 
            : 
            ExtendHelper<Extender>::Type<>
        {
            template <class C>
            Extend(C &rhs)
                :
                ExtendHelper<Extender>::Type<>(rhs)
            {
            }
        };      
    };
};

struct Data { };

Base::Type<Base> base;
Base::Type<Base>::Extend<Data> baseWithData(base);

Редактировать: обратите внимание, что мне пришлось добавить конструктор по умолчанию к ExtendHelper, потому что компилятор хотел его, но я не знаю почему.

Ответы [ 2 ]

4 голосов
/ 01 ноября 2011

Необходимо указать, что вложенное имя Type относится к шаблону. Буквально замените все вхождения ::Type< на ::template Type<.

(Это не единственная проблема; есть еще одна с конструктором ExtendHelper, которую я до сих пор пытаюсь увидеть.)

Обновление: Я думаю, в вашем внешнем Type классе отсутствует конструктор. Если вы добавите следующие два, это будет работать:

template <typename U> Type(const U &) { }  // needed for `Base::Type<Base>&` in the constructor initializer
Type()                                { }  // needed for `base` in the example code
1 голос
/ 01 ноября 2011

Ваш пример кода недействителен, AFAIK. Мне пришлось применить следующие изменения, чтобы исправить некоторые ошибки:

--- nested.cxx.orig     2011-11-01 16:58:30.234375000 +0100
+++ nested.cxx  2011-11-01 17:00:13.781250000 +0100
@@ -9,12 +9,12 @@ struct Base
             template <class U=ExtendHelper>
             struct Type
                 :
-                T::Type<U>,
+                T::template Type<U>,
                 Extender
             {
-                Type(typename T::Type<T> &rhs)
+                Type(typename T::template Type<T> &rhs)
                     :
-                    T::Type<U>(rhs)
+                    T::template Type<U>(rhs)
                 {
                 }
                 Type() {}
@@ -24,12 +24,12 @@ struct Base
         template <class Extender>
         struct Extend
             :
-            ExtendHelper<Extender>::Type<>
+            ExtendHelper<Extender>::template Type<>
         {
             template <class C>
             Extend(C &rhs)
                 :
-                ExtendHelper<Extender>::Type<>(rhs)
+                ExtendHelper<Extender>::template Type<>(rhs)
             {
             }
         };

После изменений я получаю это:

g++ -Wextra -Wall -pedantic -std=c++98 -c nested.cxx
nested.cxx: In constructor ‘Base::Type<T>::ExtendHelper<Extender>::Type<U>::Type(typename T::Type<T>&) [with U = Base::Type<Base>::ExtendHelper<Data>, Extender = Data, T = Base, typename T::Type<T> = Base::Type<Base>]’:
nested.cxx:32:60:   instantiated from ‘Base::Type<T>::Extend<Extender>::Extend(C&) [with C = Base::Type<Base>, Extender = Data, T = Base]’
nested.cxx:42:49:   instantiated from here
nested.cxx:17:44: error: no matching function for call to ‘Base::Type<Base::Type<Base>::ExtendHelper<Data> >::Type(Base::Type<Base>&)’
nested.cxx:5:5: note: candidates are: Base::Type<Base::Type<Base>::ExtendHelper<Data> >::Type(const Base::Type<Base::Type<Base>::ExtendHelper<Data> >&)
nested.cxx:5:5: note:                 Base::Type<Base::Type<Base>::ExtendHelper<Data> >::Type()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...