Зачем использовать X, а не X <T> для шаблонного конструктора и деструктора?

В Professional С++ (2е стр. 689) говорится:

Только для конструкторов и деструктора вы должны использовать X, а не X<T>.

Итак:

template<typename T>
class X{
    X();                                  // X
    ~X();                                 // X
    X<T>& operator=(const X<T>& rhs);     // X<T>
};

Почему вы не должны использовать X<T> для объявлений конструктора и деструктора?

Ответы

Ответ 1

Цитата довольно проста.

X<T> - это фактическое имя типа:

[C++11: 14.2/6]: Идентификатор простого шаблона, который называет специализацию шаблона класса, является именем класса (раздел 9).

& hellip; вы можете использовать его везде:

template<typename T>
class X
{
public:
    X<T>() {}
    ~X<T>() {}
    X<T>& operator=(const X<T>& rhs) {}
};

int main()
{
    X<int> x;
}

(живая демонстрация)

Вы можете использовать X как "стенографию", в которой аргумент шаблона будет автоматически добавлен для вас (kinda):

[C++11: 14.6.1/1]: Подобно обычным (не шаблонным) классам, шаблоны классов имеют имя с введенным классом (раздел 9). Имя введенного класса может использоваться как имя шаблона или имя типа.. Когда он используется с шаблоном-аргументом-списком, в качестве шаблона-аргумента для шаблона-шаблона шаблона или как окончательный идентификатор в специфицированном спецификаторе типа объявления шаблона класса друга, он относится к самому шаблону класса. В противном случае это эквивалентно имени шаблона, за которым следуют шаблонные параметры шаблона класса, заключенного в <>.

& hellip, но это, безусловно, нигде не требуется.

Похоже, автор пытается применить руководство по стилю, но сделал это недостаточно ясно, что он полностью зависит от вас.

Ответ 2

Здесь нет никакого отношения к X, это просто имя класса.

Поскольку конструкторы и деструкторы имеют то же имя, что и класс, и для обоих нет типа возврата, нет необходимости указывать его.