我曾与某人讨论解析C ++。他说,C ++必须在解析时实例化所有模板,而我认为并非如此。您可以简单地创建一个分析树,然后在以后实例化模板。
GCC和Clang如何处理此问题?
您的朋友是对的。 Tbe模板必须实例化。
有很多简单的例子,但我有一个方便的例子;摘自[this answer]。
main
中第一行的解析取决于IsPrime
模板的实例化(而不仅仅是解析)。如所写,如果模板参数不是IsPrime
不是素数,则会产生语法错误,但是将()
更改为(0)
将允许两种可能性都有效,但分析方式却大不相同。
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;
}