Разница между именем шаблона и идентификатором шаблона - PullRequest
8 голосов
/ 26 сентября 2010

C ++ Стандарт

Раздел 14/2:

В объявлении шаблона функции идентификатор объявления должен быть имя шаблона (т.е. не шаблон-идентификатор ). [ Примечание: в классе объявление шаблона, если идентификатор объявления - это идентификатор шаблона , объявление объявляет класс Частичная специализация шаблона.

В чем разница между template-name, template-id и type-id?

Означает ли приведенная выше цитата, что мы не можем написать что-то вроде

template <>
void templatefunction<int>(){ // ...} 

или я неправильно понял смысл?

Ответы [ 3 ]

29 голосов
/ 26 сентября 2010

Имя шаблона - это имя шаблона. В вашем примере templatefunction - это имя шаблона .

template-id - это имя шаблона со списком аргументов шаблона. В вашем примере templatefunction<int> - это template-id . A template-id указывает специализацию шаблона.

A идентификатор типа называет тип. A идентификатор шаблона - это идентификатор типа ; template-name нет (потому что он не называет тип; он называет шаблон).

Текст, который вы цитируете от 14/2, касается шаблона-объявления , который объявляет основной шаблон. Ваш пример - это не объявление шаблона , это явная специализация (14.7.3 / 1).

6 голосов
/ 26 сентября 2010

Идентификатор объявления - это синтаксический элемент, который задает имя в простом объявлении («имя типа;»). В следующих «A» и «B :: C» - идентификатор объявления

int A;
int B::C;
int A();
int *A;
int A[42];
template<typename T> void A();

Синтаксически идентификатор типа представляет собой простое объявление, в котором идентификатор объявления отсутствует. Идентификатор типа используется в качестве синтаксического элемента в аргументе типа шаблона и в приведении.

int // type-id
int* // type-id
int[] // type-id
int() // type-id
int(*)() // type-id

Имя шаблона - это имя шаблона. Синтаксически он появляется перед списком аргументов шаблона. Вышеприведенная цитата неправильно использует «имя шаблона» и «идентификатор объявления», потому что имя шаблона является простым идентификатором и не содержит никаких квалификаторов. C ++ 0x изменил текст на

В объявлении шаблона функции последний компонент идентификатора объявления должен быть именем шаблона или идентификатором оператора-функции (т. Е. Не идентификатором шаблона).

(последняя часть появляется в таких случаях, как operator+()). Даже текст C ++ 0x пропускает некоторые случаи - см. этот отчет о дефектах .

Неправильное использование «объявления-идентификатора» происходит в примечании. Заметка была заменена на C ++ 0x с

[Примечание: в объявлении шаблона класса, если имя класса ... - конец примечания]

В объявлениях шаблонов классов указанное синтаксически имя является именем класса вместо идентификатора объявления. Соотношение имени класса и объявления объявления выглядит следующим образом (очень упрощенно ...)

class class-name { ... } declarator-id;
class foo        { ... } bar;

В объявлениях шаблонов классов может быть не указан идентификатор объявления.


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


Кавычка означает, что в объявлении функции template имя не должно быть идентификатором шаблона. В вашем примере вы объявляете функцию вместо шаблона. Однако все еще есть случаи, когда явная специализация объявляет шаблон. Но это может произойти только для шаблонов функций-членов

template<typename T>
struct A {
  template<typename U>
  void f();
};

// this explicit specialization *contains* a template declaration and
// declares an identifier (a template-name) qualified by A<int>:: 
template<> template<typename U> 
void A<int>::f() { }
2 голосов
/ 26 сентября 2010

С C++ Templates: The Complete Guide Дэвид Вандевурде, Николай М. Хосуттис

8.3

Явные аргументы шаблона : за именем шаблона могут следовать явные значения аргументов шаблона, заключенные в угловые скобки. Полученное имя называется template-id .

Например:

template <typename T>
struct Demo{ 
    // ... 
};

int main()
{
   Demo <int> d; // Demo is the template name, Demo<int> is the template-id
   // ...
}

В объявлении шаблона функции идентификатор объявления должен быть именем шаблона (т.е. не идентификатором шаблона).

Например (из того, что я понял):

class A {
public:
    template <typename T> void f(T);
    template <typename T> struct X { };
};
class B : public A {
public:
    using A::f;     // fine
    using A::X      // fine

};
class C : public A {
public:
    using A::f<int>;     // ill formed, declarator-id shall not be a template id
    using A::X<double>   // ill formed, declarator-id shall not be a template id

};

Кто-то, пожалуйста, поправьте меня, если я ошибаюсь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...