Нестандартные параметры шаблона
Я понимаю, что параметр шаблона непигового типа должен быть постоянным интегральным выражением. Может ли кто-то пролить свет, почему это так?
template void foo() { // ... }
error C2993: 'std::string' : illegal type for non-type template parameter 'temp'.
Я понимаю, что такое постоянное интегральное выражение. Каковы причины не допускать нестационарные типы, такие как std::string
как в приведенном выше fragmentе?
- Дизайн шаблонов веб-приложений
- Проблема GCC: использование члена базового classа, который зависит от аргумента шаблона
- Что такое Mixins (как концепция)
- C ++ шаблон typedef
- Как достичь «виртуальной функции шаблона» в C ++
- Предложения по шаблонам электронной почты Java?
- Как определить, существует ли конкретная переменная-член в classе?
- Получить индекс типа элемента кортежа?
- Как заставить статический член инициализироваться?
- Как предотвратить создание неспециализированных шаблонов?
- перегрузка оператора друга << для шаблона classа
- Как использовать dom-repeat с объектами вместо массивов в Polymer 1.0?
- Когда следует использовать Observer и Observable
Причина, по которой вы не можете сделать это, заключается в том, что не константные выражения не могут быть проанализированы и заменены во время компиляции. Они могут меняться во время выполнения, что потребует генерации нового шаблона во время выполнения, что невозможно, потому что шаблоны являются концепцией времени компиляции.
Вот что стандарт позволяет использовать параметры шаблона непигового типа (14.1 [temp.param] p4):
Параметр шаблона, не относящийся к типу, должен иметь один из следующих (необязательно cv-квалифицированных) типов:
- интегрального или перечисляемого типа,
- указатель на объект или указатель на функцию,
- lvalue ссылка на объект или lvalue ссылку на функцию,
- указатель на член,
std::nullptr_t
.
Это недопустимо.
Однако это разрешено:
template //pointer to object void f(); template //reference to object void g();
См. §14.1 / 6,7,8 в Стандарте C ++ (2003).
Иллюстрация:
template //pointer to object void f() { cout << *temp << endl; } template //reference to object void g() { cout << temp << endl; temp += "...appended some string"; } std::string s; //must not be local as it must have external linkage! int main() { s = "can assign values locally"; f<&s>(); g(); cout << s << endl; return 0; }
Вывод:
can assign values locally can assign values locally can assign values locally...appended some string
Вы должны уметь манипулировать аргументами шаблона
template void f() { // ... } f<"foo">(); f<"bar">(); // different function!?
Теперь имплантированию необходимо будет создать уникальную последовательность символов для std::string
или, если на то пошло, любого другого произвольно определенного пользователем classа, сохраняющего определенное значение, значение которого неизвестно реализации. И кроме того, значение произвольных объектов classа невозможно вычислить во время компиляции.
Планируется рассмотреть возможность использования типов литералов в виде типов шаблонов для пост-C ++ 0x, которые инициализируются постоянными выражениями. Это может быть искажено, если элементы данных рекурсивно искалечены в соответствии со своими значениями (для базовых classов, например, мы можем применить обход глубины, сначала слева направо). Но это определенно не будет работать для произвольных classов.
Аргумент шаблона без типа, представленный в списке аргументов шаблона, представляет собой выражение, значение которого может быть определено во время компиляции. Такими аргументами должны быть:
постоянные выражения, адреса функций или объектов с внешней связью или адреса статических членов classа.
Кроме того, строковые литералы – это объекты с внутренней связью, поэтому вы не можете использовать их в качестве аргументов шаблона. Вы также не можете использовать глобальный указатель. Литералы с плавающей точкой не допускаются, учитывая очевидную возможность ошибок округления.