这是我在各种编译器中观察到的情况。似乎存在编译器错误。
template <int I>
struct X
{ };
int main(void)
{
X<(16 > 1)> a; // Works on vc9, works on g++ 4.1.2, works on Comeau 4.3.10.1
X<(int(16) > 1)> b; // Works on vc9, works on g++ 4.1.2, works on Comeau 4.3.10.1
X<(16 >> 1)> c; // Works on vc9, works on g++ 4.1.2, works on Comeau 4.3.10.1
X<(int(16) >> 1)> d; // Fails on vc9, works on g++ 4.1.2, works on Comeau 4.3.10.1
X<16 > 1> e; // Fails on vc9, works on g++ 4.1.2, fails on Comeau 4.3.10.1
X<int(16) > 1> f; // Fails on vc9, fails on g++ 4.1.2, fails on Comeau 4.3.10.1
X<16 >> 1> g; // Fails on vc9, works on g++ 4.1.2, fails on Comeau 4.3.10.1
X<int(16) >> 1> h; // Fails on vc9, works on g++ 4.1.2, fails on Comeau 4.3.10.1
}
为什么会出现这种不一致?标准允许/不允许什么?在 vc9 上使用 BOOST_AUTO 时,这种行为也会导致语法错误。在我看来,Comeau 拒绝所有不带括号的表达式是正确的。
最佳答案
C++03规则如下:
After name lookup (3.4) finds that a name is a template-name, if this name is followed by a
<
, the<
is always taken as the beginning of a template-argument-list and never as a name followed by the less-than operator. When parsing a template-id, the first non-nested>
[foot-note: A>
that encloses the type-id of adynamic_cast
,static_cast
,reinterpret_cast
orconst_cast
, or which encloses the template-arguments of a subsequent template-id, is considered nested for the purpose of this description. ] is taken as the end of the template-argument-list rather than a greater-than operator.
所以结果是:
X<(16 > 1)> a; // works
X<(int(16) > 1)> b; // works
X<(16 >> 1)> c; // works
X<(int(16) >> 1)> d; // works
X<16 > 1> e; // fails
X<int(16) > 1> f; // fails
X<16 >> 1> g; // works (">>" is not a ">" token)
X<int(16) >> 1> h; // works (">>" is not a ">" token).
但是,在 C++0x 中有以下规则
After name lookup (3.4) finds that a name is a template-name, or that an operator-function-id refers to a set of overloaded functions any member of which is a function template, if this is followed by a
<
, the<
is always taken as the delimiter of a template-argument-list and never as the less-than operator. When parsing a template-argument-list, the first non-nested > [foot-note: A>
that encloses the type-id of adynamic_cast
,static_cast
,reinterpret_cast
orconst_cast
, or which encloses the template-arguments of a subsequent template-id, is considered nested for the purpose of this description.] is taken as the ending delimiter rather than a greater-than operator. Similarly, the first non-nested>>
is treated as two consecutive but distinct>
tokens, the first of which is taken as the end of the template-argument-list and completes the template-id.
结果会是
X<(16 > 1)> a; // works
X<(int(16) > 1)> b; // works
X<(16 >> 1)> c; // works
X<(int(16) >> 1)> d; // works
X<16 > 1> e; // fails
X<int(16) > 1> f; // fails
X<16 >> 1> g; // fails (">>" translated to "> >")
X<int(16) >> 1> h; // fails (">>" translated to "> >")
测试时一定要在comeau中禁用C++0x模式
关于c++ - 为什么非类型模板参数表达式处理在编译器之间不一致?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1595859/