尽管确切的类名匹配C ++,但模板化基类初始化构造函数仍会失败

时间:2011-11-01 15:31:19

标签: c++ templates inheritance

在以下代码中,我在初始化列表

中有一个项目
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 个答案:

答案 0 :(得分:4)

您需要指定嵌套名称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 :(得分:1)

您的示例代码无效,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()