Почему шаблоны не могут быть объявлены в функции? - PullRequest
22 голосов
/ 10 августа 2010

Чтение Шаблоны 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 ]

39 голосов
/ 17 мая 2011

Проблема, вероятно, связана с историческим способом реализации шаблонов: методы ранней реализации (и некоторые до сих пор используются сегодня) требуют, чтобы все символы в шаблоне имели внешнюю связь. (Реализация выполняется путем создания эквивалентного кода в отдельном файле.) Имена, определенные внутри функции, никогда не имеют связи и не могут быть переданы вне области, в которой они были определены.

3 голосов
/ 10 августа 2010

Это означает, что вы не можете делать что-то вроде следующего

  void foo()
  {
       template <typename T> //Error
       T something;
  }

Объявления шаблонов разрешены только в глобальной области, пространстве имен или области видимости класса.:)

В чем причина этого?

Это недопустимо, потому что Стандарт говорит об этом.

ISO C ++ - 98 ( Раздел 14.2 )

A объявление шаблона может отображаться только как пространство именили объявление области видимости.

Имеет ли это смысл?

2 голосов
/ 11 января 2019

Ответ «потому что стандарт так говорит», конечно, верен, но давайте рассмотрим общие лямбды.

В 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 уже поддерживает этот синтаксис.

2 голосов
/ 10 августа 2010

Короткий ответ на вопрос, почему это так, потому что так хотели парни, написавшие компиляторы и стандарты c / c ++.Шаблоны внутри функций должны считаться слишком хаотичными и / или трудными для понимания или анализа, поэтому они запретили это.

1 голос
/ 17 мая 2011

Я предполагаю, что это сложно реализовать, поэтому это запрещено (в стандарте C ++ 03).Написание шаблонов классов вне функций - приемлемое решение с другой стороны.

1 голос
/ 10 августа 2010

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

0 голосов
/ 10 августа 2010

Что именно будет полезно? Таким образом, вы можете объявить переменные шаблона, которые вы можете использовать только внутри функции? Это действительно полезно?

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