Ваш друг прав. Шаблоны Tbe должны быть созданы, и это то, что делают компиляторы. [Примечание 1]
Есть гораздо более простые примеры, но у меня был один удобный; оно взято из этого ответа .
Разбор первой строки в main
зависит от реализации (а не только разбор) шаблона IsPrime
. Как написано, он генерирует синтаксическую ошибку, если аргумент шаблона для IsPrime
не является простым; однако изменение ()
на (0)
позволит обеим функциям быть действительными, но с очень разным анализом. (С составным аргументом шаблона typen
- это простая целочисленная константа, а typen<1>(0)
- это два сравнения, эквивалентные (typen < 1) > 0
.)
Не все примеры являются такими же надуманными, как этот. Когда я писал это, я пытался подчеркнуть другую точку зрения: правильный синтаксический анализ программы на C ++ может потребовать решения довольно сложной математической задачи, например, определения, является ли большое число простым. Это выводит C ++ далеко за пределы области контекстно-свободных языков.
template<bool V> struct answer { answer(int) {} bool operator()(){return V;}};
template<bool no, bool yes, int f, int p> struct IsPrimeHelper
: IsPrimeHelper<p % f == 0, f * f >= p, f + 2, p> {};
template<bool yes, int f, int p> struct IsPrimeHelper<true, yes, f, p> { using type = answer<false>; };
template<int f, int p> struct IsPrimeHelper<false, true, f, p> { using type = answer<true>; };
template<int I> using IsPrime = typename IsPrimeHelper<!(I&1), false, 3, I>::type;
template<int I>
struct X { static const int i = I; int a[i]; };
template<typename A> struct foo;
template<>struct foo<answer<true>>{
template<int I> using typen = X<I>;
};
template<> struct foo<answer<false>>{
static const int typen = 0;
};
int main() {
auto b = foo<IsPrime<234799>>::typen<1>(); // Syntax error if not prime
return 0;
}
Заметки
- Ира Бакстер скажет, что вы можете использовать парсер GLR, чтобы найти все возможный альтернативный анализ без создания экземпляров шаблонов, а затем выберите правильный анализ после создания экземпляра. Это правда, но ИМХО разбор не закончился, пока вы не знаете, какой синтаксический анализ правильный.