【问题标题】:Why decltype(auto) infers T& as return type, while dedicated T& does not?为什么 decltype(auto) 将 T & 推断为返回类型,而专用 & 没有?
【发布时间】:2021-09-23 08:52:13
【问题描述】:

考虑一下这个sn-p:

#include <stdexcept>

template <typename T> class MyClass;

template <typename T> struct MyClass<T &> {

  constexpr T &foo() && {
    return value != nullptr ? std::move(*value)
                            : throw std::runtime_error("foo");
  }

  constexpr decltype(auto) bar() && {
    return value != nullptr ? std::move(*value)
                            : throw std::runtime_error("bar");
  }

  T *value;
};

int main() {
  const int &good = MyClass<int &>{}.bar();
  const int &bad = MyClass<int &>{}.foo();
}

Demo

为什么方法 bar 中的返回规范 decltype(auto) 有效,而 foo 中的 T&amp; 无效?

【问题讨论】:

  • 谁说这是在演绎T&amp;?如果是这样,您不认为main 中的非常量引用会起作用吗?
  • 更好地描述症状,而不仅仅是您的解释。错误信息应包含在问题中
  • @molbdnilo - 不,它推断出T&amp;&amp;
  • 旁注:在这种情况下,我只会使用标准的保护子句,而不是试图用三元语句来破坏可读性

标签: c++ templates type-inference decltype decltype-auto


【解决方案1】:

为什么 decltype(auto) 将 T& 推断为返回类型

不,bar() 的返回类型是T&amp;&amp;,在这种情况下为int&amp;&amp;。对于decltype

如果表达式的值类别是xvalue,则decltype产生T&&;

std::move(*value) 是一个 xvalue 表达式,因此推导出的返回类型为 T&amp;&amp;

另一方面,foo 的返回类型指定为T&amp;,但std::move(*value) 是一个xvalue(右值),不能绑定到T&amp;,即对非的左值引用-const.

【讨论】:

  • 有没有办法将值作为参考返回?
  • @Juergen 可以指定返回类型为T&amp;&amp;(与bar的返回类型相同)。
猜你喜欢
  • 2017-03-18
  • 1970-01-01
  • 2015-03-17
  • 2021-11-18
  • 1970-01-01
  • 2017-08-02
  • 1970-01-01
  • 2023-03-04
  • 2019-12-10
相关资源
最近更新 更多