Параметры шаблона непигового типа, очевидно, являются типами, которые не являются типами, например:
template<int x>
void foo() { cout << x; }
В этом случае есть другие варианты, кроме int, и я хотел бы назвать этот отличный ответ.
Теперь есть одна вещь, которая меня пугает: structs. Рассмотрим:
struct Triple { int x, y, z; };
Triple t { 1, 2, 3 };
template<Triple const& t>
class Foo { };
Теперь, используя обычную нетопическую ссылочную семантику, мы можем написать:
Foo<t> f;
Что стоит отметить, что t не может быть constexpr или даже const, потому что это подразумевает внутреннюю привязку, что в основном означает, что строка не будет компилироваться. Мы можем обойти это, объявив t как const extern. Это может быть немного странно, но тот, который действительно заставило меня задуматься, почему это невозможно:
Foo<Triple { 1, 2, 3 }> f;
Мы получаем очень приличную ошибку от компилятора:
error:
Triple{1, 2, 3}не является допустимым аргументом шаблона для типаconst Triple&, потому что это не значение lvalue.
Мы не можем указать Triple в шаблоне по значению, потому что это запрещено. Однако я не понимаю реальной проблемы с этой небольшой строкой кода. Какова причина отсутствия возможности использования структур как значений. Если я могу использовать три int s, почему бы не создать структуру из трех целых чисел? Если он имеет только тривиальные специальные элементы, он не должен быть действительно различным в обработке, чем просто три переменные.