3

这是一个简单的模板;

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>() {};

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

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

4

2 回答 2

4

C++ Builder is wrong here. The reason why you should be able to use the ancestor's name in the constructor's member initializer list has to do with the concept of injected class name.

When you define a class, the compiler inserts the name of the class into that class and makes it refer to itself. This injected name is what allows you to use the name of the class without template arguments inside the class.

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

This injected name is what gets looked up when you use the name tt in the member initializer list.

(For the record, clang accepts the snippet without the template argument.)

Bonus: had you defined cc as a class template with the template parameter T and the ancestor was dependent on T, the name tt would not be found in the context of cc's constructor's member initializer list.

template <class T>
class cc : tt<T> {
    cc()
        : tt<T>() /* You must use <T> here. */
    {
    }
};
于 2011-11-01T20:49:25.607 回答
0

您可以通过使用 typedef 来避免重复:

typedef tt<int> tti;

...

class cc : public tti {

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

};
于 2011-11-01T16:02:39.843 回答