当我发现以下代码可以用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>();

https://godbolt.org/z/-LOudM

似乎clang并未考虑重载运算符,而是尝试在fold表达式中使用常规>>=运算符。

但是,如果改写了fold表达式,则clang确实会考虑重载的运算符,并且可以正常编译:

constexpr Enum maxExplicit() {
    using EnumMax::operator>>=;
    return (A >>= (B >>= C));
}

这是clang错误吗?还是折叠表示的拼写等同不完全相等?

最佳答案

[expr.prim.fold]/fold-operator:



因此>>=是折叠运算符。

[expr.prim.fold]/2:



因此(enums >>= ...)是一元右对折。

[temp.variadic]/10:



因此,(enums >>= ...)在实例化时在语义上等效于(A >>= (B >>= C))。因此,这是Clang中的错误。

关于c++ - 在using声明引入的fold表达式中使用运算符是否合法?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56898075/

10-08 22:50