#c #templates
#c #шаблоны
Вопрос:
Учитывая:
template <typename T>
class C {
C amp; operator () { ... }
};
Почему / как C
разрешено объявлять переменные и функции типа C
вместо того, чтобы указывать имя C<T>
? Я действительно не думал об этом, прежде чем работать над шаблоном со многими параметрами, которые затрудняли бы написание «собственного типа».
Есть ли какие-либо особенности этого, о которых я должен знать?
Ответ №1:
[n3290: 14.6.1/1]:
Как и обычные (не шаблонные) классы, шаблоны классов имеют введенное имя класса (пункт 9). Введенное имя класса может использоваться как имя шаблона или имя типа. Когда он используется со списком аргументов шаблона, в качестве аргумента шаблона для параметра шаблона или в качестве конечного идентификатора в детализированном спецификаторе типа объявления шаблона дружественного класса, он ссылается на сам шаблон класса. В противном случае, это эквивалентно имени шаблона, за которым следуют параметры шаблона класса, заключенного в<>
.
Предположительно, это просто удобная функция.
Комментарии:
1. Удивительно, что два человека поддержали это, в то время как я процитировал неправильный отрывок 😉 Нельзя отрицать силу цитирования стандарта — очевидно, любой части стандарта!
2. Ага, концепция, которой мне не хватало, была введена-class-name . Спасибо!
3. в c 11 имя класса не вводится, поэтому, я думаю, это вызовет ошибку
4. @Mr.Anubis: Приведенная выше цитата взята из C 11, и в ней говорится, что «шаблоны классов имеют
injected-class-name
«. Этот тестовый пример не является полным доказательством того, что я пока не доверяю реализациям, которые «полностью» следуют правилам языка C 11, но я думаю, что это, безусловно, достаточно хорошо.5. пожалуйста, обратите внимание на это: ideone.com/wAcHv , вот почему я это сказал.
Ответ №2:
Это просто синтаксический сахар.
Удобно не менять подписи ваших методов, если вам нужно изменить параметры шаблона.
Ответ №3:
Почему / как C разрешено объявлять переменные и функции типа C, а не требуется указывать C?
Это просто указано следующим образом. Имя шаблона вводится в его тело и означает фактический тип (с аргументами).
Есть ли какие-либо особенности этого, о которых я должен знать?
Ничего серьезного. Вы просто должны помнить, что это не работает для базовых классов, поэтому для выполнения CRTP вам нужно сделать
template <class T>
class A : public Base<A<T> > // not Base<A>
Комментарии:
1. За исключением, если
Base
ожидается параметр шаблона шаблона. 😉2. @Xeo: да, но в CRTP базовый класс ожидает производный тип.
3. Одно не исключает другое.