为什么 decltype(auto) 将 T& 推断为 return 类型,而专用 T& 却不是?
Why decltype(auto) infers T& as return type, while dedicated T& does not?
考虑这个片段:
#include <stdexcept>
template <typename T> class MyClass;
template <typename T> struct MyClass<T &> {
constexpr T &foo() && {
return value != nullptr ? std::move(*value)
: throw std::runtime_error("foo");
}
constexpr decltype(auto) bar() && {
return value != nullptr ? std::move(*value)
: throw std::runtime_error("bar");
}
T *value;
};
int main() {
const int &good = MyClass<int &>{}.bar();
const int &bad = MyClass<int &>{}.foo();
}
为什么方法 bar
中的 return 规范 decltype(auto)
有效,而 foo
中的 T&
无效?
Why decltype(auto) infers T& as return type
不是,bar()
的return类型是T&&
,即本例中的int&&
。对于 decltype
:
if the value category of expression is xvalue, then decltype yields T&&;
std::move(*value)
是一个 xvalue 表达式,所以推导的 return 类型是 T&&
.
另一方面,foo
的return类型被指定为T&
,但是std::move(*value)
是一个xvalue(右值)并且不能被绑定到 T&
,即对非常量的左值引用。
考虑这个片段:
#include <stdexcept>
template <typename T> class MyClass;
template <typename T> struct MyClass<T &> {
constexpr T &foo() && {
return value != nullptr ? std::move(*value)
: throw std::runtime_error("foo");
}
constexpr decltype(auto) bar() && {
return value != nullptr ? std::move(*value)
: throw std::runtime_error("bar");
}
T *value;
};
int main() {
const int &good = MyClass<int &>{}.bar();
const int &bad = MyClass<int &>{}.foo();
}
为什么方法 bar
中的 return 规范 decltype(auto)
有效,而 foo
中的 T&
无效?
Why decltype(auto) infers T& as return type
不是,bar()
的return类型是T&&
,即本例中的int&&
。对于 decltype
:
if the value category of expression is xvalue, then decltype yields T&&;
std::move(*value)
是一个 xvalue 表达式,所以推导的 return 类型是 T&&
.
另一方面,foo
的return类型被指定为T&
,但是std::move(*value)
是一个xvalue(右值)并且不能被绑定到 T&
,即对非常量的左值引用。