Mar*_*ark 19 c++ clang fold-expression c++17
当我发现以下可编译gcc
但不编译的代码时,我正在尝试在折叠表达式中使用任意函数clang
。
enum Enum {
A = 3,
B = 8,
C = 5
};
namespace EnumMax {
constexpr Enum operator>>=(const Enum left, const Enum right) {
return left < right ? right : left;
}
}
template<Enum ... enums>
constexpr Enum max() {
using EnumMax::operator>>=;
return (enums >>= ...);
}
constexpr Enum max_v = max<A, B, C>();
Run Code Online (Sandbox Code Playgroud)
似乎clang
不考虑重载运算符,而是尝试>>=
在fold表达式中使用正则运算符。
但是,如果改写了fold表达式,clang
则考虑重载运算符,并且可以正常编译:
constexpr Enum maxExplicit() {
using EnumMax::operator>>=;
return (A >>= (B >>= C));
}
Run Code Online (Sandbox Code Playgroud)
这是clang
错误吗?还是等于折叠表达式的拼写不完全相同?
\n\n\n折叠运算符:其中之一
\n\nRun Code Online (Sandbox Code Playgroud)\n+ \xe2\x80\x83\xe2\x80\x82- \xe2\x80\x83\xe2\x80\x82* \xe2\x80\x83\xe2\x80\x82/ \xe2\x80\x83\xe2\x80\x82% \xe2\x80\x83\xe2\x80\x82^ \xe2\x80\x83\xe2\x80\x82& \xe2\x80\x83\xe2\x80\x82| \xe2\x80\x83\xe2\x80\x82<< \xe2\x80\x83\xe2\x80\x82>> \n+=\xe2\x80\x83\xe2\x80\x82-=\xe2\x80\x83\xe2\x80\x82*=\xe2\x80\x83\xe2\x80\x82/=\xe2\x80\x83\xe2\x80\x82%=\xe2\x80\x83\xe2\x80\x82^=\xe2\x80\x83\xe2\x80\x82&=\xe2\x80\x83\xe2\x80\x82|=\xe2\x80\x83\xe2\x80\x82<<=\xe2\x80\x83\xe2\x80\x82>>=\xe2\x80\x83\xe2\x80\x82=\n==\xe2\x80\x83\xe2\x80\x82!=\xe2\x80\x83\xe2\x80\x82< \xe2\x80\x83\xe2\x80\x82> \xe2\x80\x83\xe2\x80\x82<=\xe2\x80\x83\xe2\x80\x82>=\xe2\x80\x83\xe2\x80\x82&&\xe2\x80\x83\xe2\x80\x82||\xe2\x80\x83\xe2\x80\x82, \xe2\x80\x83\xe2\x80\x82.* \xe2\x80\x83\xe2\x80\x82->*\n
折叠运算符>>=
也是如此。
\n\n\n形式为\n 折叠运算符的表达式称为一 元左折叠。形式为折叠运算符的表达式称为一元右折叠。一元左折叠和一元右折叠\n统称为一元折叠。在一元折叠中, 强制转换表达式应包含未展开的包 ([temp.variadic])。
\n(... op e)
op
(e op ...)
op
(enums >>= ...)
一元右折叠也是如此。
\n\n\n折叠表达式的实例化产生:
\n\n\n
\n\n- \n
[...]
- \n
E1 op (\xe2\x8b\xaf op (EN\xe2\x88\x921 op EN))
对于一元右折叠,- \n
[...]
在每种情况下,
\nop
是折叠运算符,N
是包扩展参数中的\n 个元素,每个\n 是通过实例化模式\n 并将每个包扩展参数替换为其 第\n 个元素而生成的。[...]Ei
i
因此,(enums >>= ...)
在语义上等同于(A >>= (B >>= C))
实例化它。所以这是 Clang 中的一个错误。