Обязательны ли аргументы шаблона при упоминании базового класса шаблона? - PullRequest
3 голосов
/ 01 ноября 2011

Вот простой шаблон;

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 необходимо повторять параметры шаблона каждый раз, когда шаблон tt упоминается в классе cc.

Указывает ли стандартная спецификация C ++ на необходимость постоянного повторения параметров шаблона или компилятор C ++ Builder неверен?

Ответы [ 2 ]

3 голосов
/ 02 ноября 2011

C ++ Builder здесь не так. Причина, по которой вы должны иметь возможность использовать имя предка в списке инициализатора члена конструктора, связана с концепцией введенного имени класса .

Когда вы определяете класс, компилятор вставляет имя класса в этот класс и заставляет его ссылаться на себя. Это внедренное имя позволяет вам использовать имя класса без аргументов шаблона внутри класса.

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

Это введенное имя - то, что ищется, когда вы используете имя tt в списке инициализатора члена.

(Для записи clang принимает фрагмент без аргумента шаблона.)

Бонус: если бы вы определили cc как шаблон класса с параметром шаблона T и предок зависел от T, имя tt не будет найдено в контексте из списка инициализаторов элементов cc.

template <class T>
class cc : tt<T> {
    cc()
        : tt<T>() /* You must use <T> here. */
    {
    }
};
0 голосов
/ 01 ноября 2011

вы можете избежать повторений, используя typedef:

typedef tt<int> tti;

...

class cc : public tti {

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

};
...