为什么`decltype(static_cast <T>(…))`并不总是`T`?


24

对于以下代码,除最后一个断言外,所有代码均通过:

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>而不总是返回a T


我加T_cast i{1};我得到invalid initialization of non-const reference of type 'T_cast' {aka 'int (&)(int)'} from an rvalue of type '<brace-enclosed initializer list>',所以不管什么原因T_cast都是a int (&)(int)而不是a int (&&)(int)
凯文

Answers:


21

这是硬编码在的定义中static_cast

[expr.static.cast](重点是我的)

1表达式static_­cast<T>(v)的结果是将表达式转换v为type 的结果T如果T为左值引用类型或对函数类型的右值引用,则结果为左值;如果T是对对象类型的右值引用,则结果为xvalue;否则,结果为prvalue。该static_­cast 经营者不得抛弃常量性。

decltype 尊重其操作数的值类别,并为左值表达式生成左值引用。

推理可能是由于函数名称本身始终是左值,因此函数类型的右值不能出现在“野外”中。因此,强制转换为这种类型可能毫无意义。


这个问题更详细地解决了“函数类型的右值“不在野外出现””
Eric
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.