当提到模板基类时,是否在任何地方都需要模板参数

Are template arguments required everywhere when mentioning a template base class?

本文关键字:任何地 参数 基类 是否      更新时间:2023-10-16

这是一个简单的模板;

template <class T>
class tt {
    private:
        T  x;
    public:
        tt() {x=0;};
        Add(T p) {x += p;};
};

…然后是它的子类;

class cc : public tt<int> {
    public:
        cc() : tt() {};
};

这在VC中可以很好地编译,但在c++ Builder (XE)中不行,它会给出E2102错误。c++ Builder编译器需要在cc类的构造函数上使用以下语法进行编译:

cc() : tt<int>() {};

实际上,c++ Builder编译器需要每次在cc类中提到tt模板时都重复模板参数。

标准c++规范是否指定需要不断重复模板参数,还是c++ Builder编译器错误?

c++ Builder这里是错误的。在构造函数的成员初始化列表中使用祖先类名的原因与注入类名的概念有关。

当定义一个类时,编译器将类名插入到该类中,并使其引用自己。这个注入的名称允许你使用类的名称,而不需要在类内部使用模板参数。

template <class T>
struct tt {
    // The compiler behaves as if there was the following.
    // typedef tt<T> tt;
};

当您在成员初始化列表中使用名称tt时,将查找这个注入的名称。

(根据记录,clang接受不带template参数的代码片段。)

附注:如果您将cc定义为模板形参T的类模板,并且祖先依赖于T,则在cc的构造函数的成员初始化列表中不会找到名称tt

template <class T>
class cc : tt<T> {
    cc()
        : tt<T>() /* You must use <T> here. */
    {
    }
};

您可以使用typedef:

来避免重复。
typedef tt<int> tti;

class cc : public tti {
    public:
        cc() : tti() {};
};