Что означает `шаблон класса Пример <int>;` для C ++ 11? - PullRequest
0 голосов
/ 28 октября 2018

На меня ссылалась Явная статья о создании шаблона на cplusplus.com , в которой приведен следующий пример:

template <typename T> class Example
{
public:
    Example( T test )
    {
        _data = test;
    }
    void setTest(T test)
    {
        _data = T;
    }
private:
    T _data;
};

class template Example<int>;
class template Example<float>;
class template Example<double>;

Помимо того, что мне кажется ошибкой, когдаПопытка присвоения типа переменной-члену - _data = T вместо того, что я предполагаю, должно быть _data = test - я не понимаю, что именно последние 3 строки объявляют или инструктируют компилятору, точно?

Я знаю, что такое шаблоны, создавал с ними программы и в целом знаю об их создании и специализации.У меня, вероятно, есть некоторые дыры в понимании последних двух, но я, как правило, инструктирую явное создание экземпляра шаблона, используя, например, форму template class Example<int>;, а не форму, показанную во фрагменте.

Я пытался скомпилироватьфрагмент с использованием g++ -std=c++11 -pedantic, и он прекрасно компилируется и без предупреждений (я исправил ошибку _date = T выше первой).

Это произошло после того, как я прокомментировал ответ на связанный вопрос иЯ все еще не уверен, является ли какая-либо из последних 3 строк во фрагменте специализацией или созданием шаблона.

Я также попытался найти соответствующее правило создания грамматики (которое разрешает template после class) вчерновик C ++ 11, опубликованный ISO , но с пустыми руками.

Ответы [ 2 ]

0 голосов
/ 29 октября 2018

Я вижу здесь две ошибки:

  1. GCC обрабатывает ключевое слово template здесь как template disambiguator и поэтому считает, что class template Example<int> эквивалентно class Example<int>.Это неверно, потому что грамматика C ++ допускает, что разногласие template следует только после ::, . или ->. (C ++ 11, как изначально написано, позволяет class template Example<int>, но это было исправлено cwg 1707 .)
  2. GCC неправильно допускает объявление типа class Example<int>;,Хотя class Example<int>; соответствует грамматике simple-объявление , оно не соответствует требованию в [dcl.dcl] / 5 , в котором говорится, чтообъявление должно объявить или переопределить что-то (класс / перечисление / перечислитель / typedef / переменная / функция).

Первый был зарегистрирован как ошибка GCC 87781 , последний как Ошибка GCC 87783 .

Обновление: Ошибка GCC 87781 теперь исправлена ​​ r266285 .

0 голосов
/ 28 октября 2018

Мы можем видеть из следующего Godbolt пример это плохо сформировано в соответствии с Clang и MSVC и глядя на черновик стандартного раздела на Явное создание экземпляров section [temp.в явном виде] Я не вижу никаких оправданий для gcc, чтобы принять его.

Я считаю, что статья "возможно" означала, учитывая, что тема была:

template class Example<int>;
template class Example<float>;
template class Example<double>;

и это действительно правильно сформирован с помощью gcc / clang / MSVC .

Похоже, что до C ++ 11 эта грамматика была разрешена, см. отчет о дефекте 1707: шаблон в сложном типеспецификатор без вложенного-спецификатора имени ( выделение шахты ):

Грамматика для уточненного спецификатора типа в 10.1.7.3 [dcl.type.elab] читаетчастично,

elaborated-type-specifier:
    class-key nested-name-specifieropt templateopt simple-template-id

Этот позволяет использовать ключевое слово template без спецификатора вложенного имени, например, struct template S. Это несовместимо сдругое использование ключевого слова шаблона.Возможно, было бы лучше разделить производство на две части и разрешить ключевое слово только после спецификатора вложенного имени:

....

Так что это имеет немного больше смысла с этим комментарием , что -ansi вызывает предупреждение.

Другой ответчик подал два сообщения об ошибках .

cppreference имеет хорошее мнениеЯвная инстанциация и этот вопрос SO Явная инстанциация - когда он используется? объясняет более подробно, почему это полезно.

Также обратите внимание, мы можем видеть эту Мета публикацию: Ссылки были изменены на cppreference.com , о котором известно, что сайт содержит неверную информацию, и в целом сообщество предпочитает cppreference в качестве надежной ссылки на C ++.

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