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

时间:2019-10-05 21:39:34

标签: c++ static-cast

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

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

1 个答案:

答案 0 :(得分:21)

这在static_cast的定义中进行了硬编码:

  

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

     

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

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

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