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

Why is `decltype(static_cast<T>(...))` not always `T`?

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

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

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

[expr.static.cast] (emphasis mine)

1 The result of the expression static_­cast<T>(v) is the result of converting the expression v to type T. If T is an lvalue reference type or an rvalue reference to function type, the result is an lvalue; if T is an rvalue reference to object type, the result is an xvalue; otherwise, the result is a prvalue. The static_­cast operator shall not cast away constness.

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

原因可能是函数名本身总是左值,因此函数类型的右值不能出现"in the wild"。因此,转换为该类型可能没有什么意义。