Должны ли шаблоны действительно быть конструкциями времени компиляции? - PullRequest
13 голосов
/ 12 мая 2011

Действительно ли стандарт C ++ требует , что шаблоны должны создаваться во время компиляции, а не во время выполнения?

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

Ответы [ 3 ]

9 голосов
/ 12 мая 2011

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

В более строгом смысле стандарт рассматривает "перевод" как единое целое; реализация может, и реализации имеют (и я думаю, что некоторые все еще делают) отложить создание экземпляров до времени ссылки. Что приводит к интересным вопросам, когда задействовано динамическое связывание. Но в стандарте об этом ничего не сказано: динамическое связывание - это действительно неопределенное поведение, насколько это касается стандарта, так что это зависит от реализации.

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

7 голосов
/ 12 мая 2011

Вы не можете создавать типы в программе на C ++ во время выполнения (пока она выполняется); все они известны во время компиляции. Даже динамически загружаемые разделяемые библиотеки не меняют этого; набор типов в библиотеке известен во время компиляции (когда библиотека компилируется), и программа загрузки должна иметь возможность обрабатывать типы, предоставляемые библиотекой.

Таким образом, нет необходимости в оценке шаблона во время выполнения; информация известна во время компиляции.

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

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

0 голосов
/ 12 мая 2011

У меня нет привычки читать стандарт, но язык программирования Страуструпа C ++ очень полезен.

A.9 Шаблоны: дает грамматику для объявления шаблона;параметр-типа - это класс, имя типа или другой шаблон, поэтому тип известен как статический.(Это не динамично. Можно представить объект typeinfo, если бы C ++ был динамическим языком. Но это был не ваш вопрос.)

C.13.8.3 Привязка точки инстанции: говорит, что точка инстанцированиядля шаблона непосредственно перед объявлением, используя его.

Приведенный пример касается разрешения имен в определении шаблона в правильную область.Это было бы очень сложно сделать во время выполнения!

например, из Stroustrup C.13.8.3:

template<class T> void f(T a) { g(a); }

void g(int);

void h()
{
    extern g(double);
    f(2);
}

"Здесь точка создания экземпляра для f находится непосредственно перед h (), так что g (), вызываемая в f (), является глобальным g (int), а не локальным g (double). "

Я думаю, это не исключает JIT, но на практикесоздание шаблона f требует знания правильного разрешения g в определенной строке.Как говорит Джонатан, вам понадобятся сервисы компилятора как часть времени выполнения, а также полный контекст, созданный в компиляторе при компиляции этого модуля.Если это не работа во время компиляции, я не знаю, что это такое.

РЕДАКТИРОВАТЬ: Все это опирается на античную версию стандарта C ++.

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