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
它是編譯器錯誤嗎?
uj5u.com熱心網友回復:
g 在這里實際上是正確的。來自[temp.names]/3(C 20 草案 N4860):
當一個名稱被認為是一個模板名稱,并且它后面跟著一個 a
<時,<總是將其作為模板引數串列的分隔符,而不是作為小于運算子。決議template-argument-list時,第一個非嵌套>的被視為結束分隔符,而不是大于運算子。類似地,第一個非嵌套>>的被視為兩個連續但不同的>標記,其中第一個被視為模板引數串列的末尾并完成了模板 ID。[注意:此替換規則產生的第二個>令牌可能會終止封閉的模板ID構造,或者它可能是不同構造的一部分(例如,演員表)。— 尾注] [示例: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—結束示例]
被>>視為兩個>令牌。如果需要,您可以將其括在括號中以強制執行您正在嘗試執行的操作。
template<auto T>
struct S { };
int main() {
S<[]{int x,y; (x>>y);}> s2; // now compiles fine
}
注意:可能接受或拒絕都是正確的,因為嵌套的含義有點模糊。看評論。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/526412.html
上一篇:重新定義虛函式呼叫
