【问题标题】:Why is `decltype(static_cast<T>(...))` not always `T`?为什么`decltype(static_cast<T>(...))`并不总是`T`?
【发布时间】:2019-10-05 21:39:34
【问题描述】:

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

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&lt;T&gt; 并不总是返回T

【问题讨论】:

  • 我添加T_cast i{1}; 我得到invalid initialization of non-const reference of type 'T_cast' {aka 'int (&amp;)(int)'} from an rvalue of type '&lt;brace-enclosed initializer list&gt;',所以无论出于何种原因T_castint (&amp;)(int) 而不是int (&amp;&amp;)(int)

标签: c++ static-cast


【解决方案1】:

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

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

1 表达式static_­cast&lt;T&gt;(v) 的结果就是结果 将表达式v 转换为类型T如果T 是左值 引用类型或对函数类型的右值引用,结果是 一个左值;如果T 是对对象类型的右值引用,则结果为 一个极值;否则,结果为纯右值。 static_­cast 运算符不应抛弃常量。

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

原因可能是函数名本身总是左值,因此函数类型的右值不能“随意”出现。因此,强制转换为该类型可能没有什么意义。

【讨论】:

  • this question 地址更详细“函数类型的右值[s] [not]出现[ing]”在野外“”
猜你喜欢
  • 2016-11-10
  • 2019-04-14
  • 2016-10-24
  • 2017-12-31
  • 2022-12-21
  • 2012-10-23
  • 2020-09-19
  • 2014-06-12
  • 2011-05-12
相关资源
最近更新 更多