Подтвердить что ты не робот

Перегрузка класса шаблона с помощью функции шаблона

С++ позволяет использовать класс и функцию с тем же именем в одном пространстве имен:

struct S {};
void S() {}

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

Также возможно создать шаблон функции и использовать оба из них:

template <class T>
void S() {}

struct S {};

Но использование шаблона struct запрещено

void S() {}

template <class T>
struct S {};

и выдает ошибку следующим образом:

error: redefinition of 'S' as different kind of symbol

В чем причина этого? Почему бы не позволить использовать шаблонную структуру здесь? Есть ли ситуация, когда использование явного ключевого слова struct до S (например, для версии без шаблонов) не могло решить конфликт имен, если он был разрешен? Может быть, есть предложение?

4b9b3361

Ответ 1

С++ позволяет использовать класс и функцию с тем же именем в одном пространстве имен.

   struct S {};
   void S() {}

Обычно, когда вы объявляете struct S, вы можете ссылаться на тип двумя способами: как S и как struct S. Но это только до тех пор, пока вы не объявите что-то еще с именем S, например, функцию. Когда вы это сделаете, имя типа не будет S. Это только struct S. Для функции зарезервировано имя S.

Это делается для совместимости с C. C-кодом часто использует это устройство. В отличие от С++, C помещает теги struct и union в другое пространство имен из нормальных идентификаторов, а struct S нельзя назвать просто S.

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

Поскольку class почти синоним struct, это делается и для ключевого слова class.

Но у C нет шаблонов, и нет необходимости обеспечивать обратную совместимость для них, поэтому такое исключение для шаблонов классов не создается.

Ответ 2

Я думаю, что имя шаблона функции разрешено быть таким же, как что-то еще, чтобы разрешить перегрузку, в то время как имя шаблона класса явно запрещено, чтобы соответствовать чему-то другому в соответствии с

14 Шаблоны [temp]

  1. Шаблон класса не должен иметь то же имя, что и любой другой шаблон, класс, функция, переменная, перечисление, перечислитель, пространство имен или тип в той же области (3.3), за исключением случаев, указанных в (14.5.5).

[обновление] остальная часть этой части заставляет меня думать, что случай с шаблоном функции, не вызывающим ту же ошибку, нарушает стандартные требования:

За исключением того, что шаблон функции может быть перегружен либо несимвольными функциями (8.3.5) с тем же именем, либо с помощью других шаблонов функций с тем же именем (14.8.3), имя шаблона, объявленное в пространстве имен объем или класс область видимости должна быть уникальной в этой области.

и VS/clang/gcc, похоже, не согласны с этим godbolt