static_cast使用显式右值转换运算符

static_cast with an explicit rvalue conversion operator

本文关键字:转换 运算符 cast static      更新时间:2023-10-16

我正在编写一个简单的包装类,我想为包装类型提供显式转换运算符。以下代码编译良好,gcc

class wrap
{
    double value;
public:
    explicit wrap(double x) : value(x) {}
    explicit operator double&&() && { return std::move(value); }
};
int main() {
    wrap w(5);
    double && x (std::move(w) ); //ok
    double && y = static_cast<double&&>(std::move(w)); //clang reports an error here
}

但是clang报告了一个error: cannot cast from lvalue of type 'typename std::remove_reference<wrap &>::type' (aka 'wrap') to rvalue reference type 'double &&'; types are not compatible.

据我所知(见最新草案,5.2.9 §4),static_cast<T>(e)具有相同的语义T t(e),但 clang 并不拒绝后者。

哪个编译器是正确的?

这是 clang bug 19917。从您提到的标准部分 §5.2.9/4:

表达式e可以使用表单static_cast<T>(e)static_cast显式转换为类型T 如果声明T t(e);格式正确,对于某些发明的临时变量t

在这种情况下,T t(e); 格式正确,并且可以在两个编译器上进行编译,因此static_cast<T>(e)也应该如此。海湾合作委员会正确地接受了它。