Sum*_*ant 9 c++ compiler-construction templates
以下是我在各种编译器中观察到的内容.似乎有编译器错误.
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
}
Run Code Online (Sandbox Code Playgroud)
为什么会出现这种不一致?标准允许/禁止的是什么?在vc9上使用BOOST_AUTO时,此类行为也会导致语法错误.在我看来,通过拒绝所有没有括号的表达式,Comeau正在做正确的工作.
C++ 03的规则如下:
在名称查找(3.4)发现名称是模板名称后,如果此名称后跟a
<,<则始终将其作为模板参数列表的开头,并且永远不会作为名称后跟小于运算符.当解析模板id,第一非嵌套>[脚音符:一个>包围的类型-IDdynamic_cast,static_cast,reinterpret_cast或const_cast,或包围随后模板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; // works (">>" is not a ">" token)
X<int(16) >> 1> h; // works (">>" is not a ">" token).
Run Code Online (Sandbox Code Playgroud)
但是,在C++ 0x中,以下是规则
在名称查找(3.4)之后发现名称是模板名称,或者operator-function-id引用一组重载函数,其中任何成员都是函数模板,如果后跟a
<,<则始终为作为模板参数列表的分隔符,从不作为小于运算符.当解析模板参数列表中,第一个非嵌套> [脚音符:一个>包围的类型-IDdynamic_cast,static_cast,reinterpret_cast或const_cast,或包围随后模板id的模板的参数,被认为是嵌套为了本说明的目的,将...作为结束分隔符而不是大于运算符.类似地,第一个非嵌套>>被视为两个连续但不同的>标记,其中第一个被视为template-argument-list的结尾并完成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 "> >")
Run Code Online (Sandbox Code Playgroud)
测试时一定要在comeau中禁用C++ 0x模式
| 归档时间: |
|
| 查看次数: |
414 次 |
| 最近记录: |