尽管类名与C++完全匹配,但模板基类初始化构造函数失败

Templated base class initialization constructor fails despite exact class name match C++

本文关键字:基类 失败 构造函数 初始化 C++      更新时间:2023-10-16

在下面的代码中,我在初始值设定项列表中有一个项

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添加一个默认构造函数,因为编译器想要一个,但我不知道为什么。

您需要指定嵌套名称Type引用模板。用::template Type<从字面上替换所有出现的::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

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