Почему шаблоны не могут быть объявлены в функции?
Чтение шаблонов C++: полное руководство
Обратите внимание, что шаблоны не могут быть объявлены в функции
Он не дает объяснения и / или перекрестной ссылки на любую другую главу в книге или на внешнем ресурсе.
Может ли кто-нибудь помочь в объяснении этого. Возможно, это будет объяснено позже в книге, но пока нет. Если объяснено ранее, я, должно быть, пропустил это.
Пример:
int main()
{
class DummyClass // This compiles ok
{
int object;
};
template <typename T> // compile error "expected primary-expression before "template""
class DummyTemplate
{
T object;
};
return 0;
}
Я также не понимаю сообщение об ошибке от gcc. Сообщение об ошибке говорит:
expected primary-expression before "template"
7 ответов
Это означает, что вы не можете сделать что-то вроде следующего
void foo()
{
template <typename T> //Error
T something;
}
Объявления шаблонов разрешены только в глобальном пространстве, пространстве имен или области видимости.:)
В чем причина этого?
Это не разрешено, потому что Стандарт говорит так.
ISO C++ - 98 (раздел 14.2)
Объявление шаблона может появляться только как объявление пространства имен или области видимости.
Имеет ли это смысл?
Проблема, вероятно, связана с историческим способом реализации шаблонов: методы ранней реализации (а некоторые до сих пор используются сегодня) требуют, чтобы все символы в шаблоне имели внешнюю связь. (Реализация выполняется путем создания эквивалентного кода в отдельном файле.) Имена, определенные внутри функции, никогда не имеют связи и не могут быть использованы вне области, в которой они были определены.
Ответ "потому что стандарт так говорит", конечно, правильный, но давайте рассмотрим общие лямбды.
В C++14 и C++17 универсальные лямбды являются единственным способом написания шаблонного кода, о котором я знаю:
auto lambda = [](auto x) { };
lambda.operator()<int>(0);
Технически, вы можете написать любой код шаблона именно с этим. Хотя вам придется много работать, чтобы обойти различные ограничения этого подхода.
Это будет проще в C++20, хотя. С помощью списка параметров шаблона в общих лямбдах вы сможете написать код, подобный этому:
auto size = []<class T>() { return sizeof(T); };
static_assert(4 == size.operator()<int>());
GCC уже поддерживает этот синтаксис.
Короткий ответ на вопрос, почему это так, заключается в том, что так хотели парни, написавшие компиляторы и стандарты c/ C++. Шаблоны внутри функций должны были считаться слишком хаотичными и / или трудными для понимания или анализа, поэтому они запрещали это.
Единственный раз, когда это было бы полезно, было бы, если вы создали несколько экземпляров шаблона с разными типами с помощью одной функции. В любом случае переместите ваши частные классы из ваших функций. Если это начинает загромождать ваши классы, то они слишком велики и требуют рефакторинга.
Я предполагаю, что это трудно реализовать, поэтому это запрещено. Написание шаблонов классов вне функций - приемлемое решение с другой стороны.
Какой именно будет польза? Таким образом, вы можете объявить переменные шаблона, которые вы можете использовать только внутри функции? Это действительно полезно?