Oli*_*liv 7 c++ casting language-lawyer compiler-bug
根据标准,带支撑的函数式转换总是会产生一个纯右值,[expr.cast]/2
否则,表达式是指定类型的纯右值,其结果对象是用初始化程序直接初始化的。
当指定类型是引用类型时,这很难解释,因为它可能发生在泛型编程中。在这种情况下,编译器采用了特定的行为:
#include <type_traits>
struct A {
A ()=default;
A (const A&);
};
template <class T, class U>
decltype(auto)
f(U& a) {
static_assert (std::is_same_v <decltype (T{a}), T>);
return T{a};
}
#if defined(__clang__) || defined(_MSC_VER)
void g1(A a){
decltype(auto) v = f<A&>(a); //GCC: error try to bind a prvalue to a non-const lvalue
static_assert (std::is_same_v <decltype(v), A&>);
}
#endif
void g2(A a){
decltype(auto) v = f<const A&>(a); //GCC: call the copy constructor of A
//MSVC and Clang: a no op (direct reference binding)
static_assert (std::is_same_v <decltype(v), const A&>);
}
Run Code Online (Sandbox Code Playgroud)
对于 Clang,GCC 和 MSVC 同意decltype(T{a})whereT is A&是 type的事实A&。这意味着根据 decltype 规范,结果不是纯右值。所以看起来这些编译器都不符合标准。
T{a}对于 Clang 和 MSVC的评估只是直接引用绑定。
GCC 拒绝编译g1. 表达式T{a}构造了 的副本,a然后临时绑定到的结果T{a}(这可以在此处模板 h 的显式实例化的程序集中看到)。
在这种情况下,任何编译器都正确吗?还是只是“无需诊断”的情况?
| 归档时间: |
|
| 查看次数: |
88 次 |
| 最近记录: |