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

4

1 回答 1

21

这在 的定义中是硬编码的static_cast

[expr.static.cast](强调我的)

1表达式static_­cast<T>(v)的结果是将表达式转换v为类型的结果T如果T是左值引用类型或对函数类型的右值引用,则结果为左值;如果T是对对象类型的右值引用,则结果是一个 xvalue;否则,结果为纯右值。操作者static_­cast 不应抛弃常量。

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

推理可能是由于函数名称本身总是左值,因此函数类型的右值不能“在野外”出现。因此,转换为该类型可能没有什么意义。

于 2019-10-05T22:01:33.247 回答