以下功能(在我的意图中)是获取一个右值并将其作为左值呈现。
auto constexpr RtoL = [](auto&& r) -> decltype(auto) {
static_assert(std::is_rvalue_reference_v<decltype(r)>, "Gimme rvalues, not lvalues.");
return (r);
};
我想在我可以保证没有真正从 xvalue 移动的情况下使用它(例如,它是通过 rvalue 转换为 rvalue 的std::move
,但没有利用它),所以我会用 xvalues 来调用它,而不是 prvalues。
无论如何,编译器(嗯,GCC 的版本)似乎对上述代码的有效性有不同的看法。具体来说,鉴于这种用法:
int main() {
int x{3};
RtoL(std::move(x));
}
GCC 11.2 认为它无效:
<source>:9:14: error: cannot bind rvalue reference of type 'int&&' to lvalue of type 'int'
9 | return (r);
| ^
而 GCC 10.3 和其他编译器认为它是有效的。
此外,将 return 语句从
return (r);
至
return static_cast<decltype(r)&>(r);
使他们都同意代码是正确的。
从标准的角度来看,真相在哪里?