对于以下代码,除最后一个断言外,所有消息均通过:
template<typename T>
constexpr void assert_static_cast_identity() {
using T_cast = decltype(static_cast<T>(std::declval<T>()));
static_assert(std::is_same_v<T_cast, T>);
}
int main() {
assert_static_cast_identity<int>();
assert_static_cast_identity<int&>();
assert_static_cast_identity<int&&>();
// assert_static_cast_identity<int(int)>(); // illegal cast
assert_static_cast_identity<int (&)(int)>();
assert_static_cast_identity<int (&&)(int)>(); // static assert fails
}
为什么最后一个断言失败,并且static_cast<T>
并不总是返回T
?
答案 0 :(得分:21)
这在static_cast
的定义中进行了硬编码:
[expr.static.cast] (强调我的意思)
1表达式
static_cast<T>(v)
的结果是结果 将表达式v
转换为类型T
的过程。 如果T
是左值 引用类型或函数类型的右值引用,结果是 左值;如果T
是对对象类型的右值引用,则结果为 一个xvalue;否则,结果为prvalue。static_cast
操作员不得抛弃常数。
decltype
尊重其操作数的值类别,并为左值表达式生成左值引用。
推理可能是由于函数名称本身始终是左值,因此函数类型的右值不能“在野外”出现。因此,强制转换为这种类型可能毫无意义。