c++ - 用作模板参数的 lambda 正文中的右位移位在 GCC 上无法编译

标签 c++ templates gcc c++20 compiler-bug

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
}

错误:

error: expected ';' before '>>' token
      |     S<[]{int x,y; x>>y;}> s2;
      |                    ^~
      |                    ;

但是,当我显式调用 operator>> 时,GCC 会接受它

struct S2 {
  void operator>>(S2 arg) { }
};
S<[]{S2 x,y; x.operator>>(y);}> s2; // compiles

当我将 lambda 定义移到模板参数列表之外时,它也会编译

auto lam = []{int x,y; x>>y;}; 
S<lam> s; // compiles

这是编译器错误吗?

最佳答案

g++ 在这里实际上是正确的。来自 [temp.names]/3 ( C++20 Draft N4860 ):

When a name is considered to be a template-name, and it 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 > 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. [Note: The second > token produced by this replacement rule may terminate an enclosing template-id construct or it may be part of a different construct (e.g., a cast). — end note] [Example:

template<int i> class X { /* ... */ };
X< 1>2 > x1;                            // syntax error
X<(1>2)> x2;                            // OK

template<class T> class Y { /* ... */ };
Y<X<1>> x3;                             // OK, same as Y<X<1> > x3;
Y<X<6>>1>> x4;                          // syntax error
Y<X<(6>>1)>> x5;                        // OK

end example]

>>被视为两个 > token 。如果需要,您可以将其括在方括号中以强制执行您正在尝试执行的操作。

template<auto T>
struct S { };

int main() {
  S<[]{int x,y; (x>>y);}> s2; // now compiles fine
}

注意:可能接受或拒绝都是正确的,因为嵌套的含义有点模糊。查看评论。

关于c++ - 用作模板参数的 lambda 正文中的右位移位在 GCC 上无法编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74293348/

相关文章:

c++ - UE4项目链接错误,描述为空

multithreading - 解析多线程make的输出(-j N)

c++ - 正确实现 WlanHostedNetwork 函数的 WlanSetSecuritySettings

c++ - 字符串流数学运算

c++ - 制作奇怪的多态性

使用多维数组的 C++ 模板

c++ - 类型类方法的参数推导(由 const 限定符重载)在 gcc 中以尾随返回类型失败,但在 clang 中没有

c++ - 如何从模板结构创建二维数组

xcode - GCC 4.0、4.2 和 LLVM ABI 兼容性

linux - 链接器在传递给它的目标文件上删除字符?