mic*_*huu 2 c++ gcc templates compiler-bug c++20
GCC 不会编译此代码,而其他编译器(clang、msvc)会编译此代码
template<auto T>
struct S { };
int main() {
S<[]{int x,y; x<<y;}> s1; // compiles fine
S<[]{int x,y; x>>y;}> s2; // error
}
Run Code Online (Sandbox Code Playgroud)
错误:
error: expected ';' before '>>' token
| S<[]{int x,y; x>>y;}> s2;
| ^~
| ;
Run Code Online (Sandbox Code Playgroud)
但是,当我明确调用时operator>>,GCC 接受它
struct S2 {
void operator>>(S2 arg) { }
};
S<[]{S2 x,y; x.operator>>(y);}> s2; // compiles
Run Code Online (Sandbox Code Playgroud)
当我将 lambda 定义移到模板参数列表之外时,它也会进行编译
auto lam = []{int x,y; x>>y;};
S<lam> s; // compiles
Run Code Online (Sandbox Code Playgroud)
这是编译器错误吗?
g++ 这里实际上是正确的。来自[temp.names]/3(C++20 草案 N4860):
\n\n当名称被认为是template-name且后跟 a 时
\n<,始终被视为template-argument-list<的分隔符,而绝不会被视为小于运算符。解析template-argument-list时,第一个非嵌套的被视为结束分隔符而不是大于运算符。类似地,第一个非嵌套被视为两个连续但不同的标记,其中第一个被视为template-argument-list的末尾并完成template-id。[注意:此替换规则生成的第二个标记可能终止封闭的template-id构造,或者它可能是不同构造的一部分(例如,强制转换)。\xe2\x80\x94 尾注] [示例:>>>>>Run Code Online (Sandbox Code Playgroud)\ntemplate<int i> class X { /* ... */ };\nX< 1>2 > x1; // syntax error\nX<(1>2)> x2; // OK\n\ntemplate<class T> class Y { /* ... */ };\nY<X<1>> x3; // OK, same as Y<X<1> > x3;\nY<X<6>>1>> x4; // syntax error\nY<X<(6>>1)>> x5; // OK\n\xe2\x80\x94结束示例]
\n
被>>视为两个>令牌。如果您愿意,您可以将其括在括号中以强制执行您想要执行的操作。
template<auto T>\nstruct S { };\n\nint main() {\n S<[]{int x,y; (x>>y);}> s2; // now compiles fine\n}\nRun Code Online (Sandbox Code Playgroud)\n注意:接受或拒绝可能都是正确的,因为嵌套的含义有点模糊。看评论。
\n| 归档时间: |
|
| 查看次数: |
116 次 |
| 最近记录: |