C++ decltype(自动)是否使尾部返回类型过时?

C++ decltype(自动)是否使尾部返回类型过时?,c++,c++17,c++20,trailing-return-type,decltype-auto,C++,C++17,C++20,Trailing Return Type,Decltype Auto,关于后续返回类型、auto返回类型推断和非常有用的decltype(auto),已经有很多问题和答案。但是我没有找到一个关于是否需要尾部返回类型的答案,因为我们有decltype(auto)。是否存在尾部返回类型解决的情况,其中decltype(auto)无法使用或不起作用(给出意外/不正确的结果)和首先需要后面的返回类型?一个简单的例子是,在定义函数并推断返回类型之前调用函数: decltype(auto) bar(); // doesn't help decltype(auto) foo(

关于后续返回类型、
auto
返回类型推断和非常有用的
decltype(auto)
,已经有很多问题和答案。但是我没有找到一个关于是否需要尾部返回类型的答案,因为我们有
decltype(auto)
。是否存在尾部返回类型解决的情况,其中
decltype(auto)
无法使用或不起作用(给出意外/不正确的结果)首先需要后面的返回类型?

一个简单的例子是,在定义函数并推断返回类型之前调用函数:

decltype(auto) bar(); // doesn't help

decltype(auto) foo() { bar(); } // error: returned type of `bar` is unknown

decltype(auto) bar() { foo(); }
decltype(auto)
(以及更普遍的推断返回类型)和尾部返回类型是正交特征

你可以有:

  • decltype(auto)f(){}
  • auto f()->decltype(auto){}
尾随返回类型 尾随返回类型很好,尤其是对函数名之前没有的上下文的访问

  • 至于模板:

    template <typename T>
    auto f(T x) -> decltype(bar(x));
    

    template <typename T>
    decltype(bar(std::declval<T&>())) f(T x);
    
    C::iterator C::begin();
    
唯一需要它的地方是lambda(如果您有/想要显式指定返回类型):

  • []()->某些类型{/*…*/}
  • []()->自动{/*…*/}
    (相当于
    [](){/*…*/}
  • []()->decltype(自动){/*…*/}
我们必须定义lambda的返回类型的情况是它应该返回引用类型

推断返回类型 使用
decltype(auto)
auto
完成

decltype(auto)
auto
演绎类型不同,主要表现为
T&
T

导出的返回类型需要主体的定义


它们也不允许使用SFINAE,因为没有替换。

并且尾随返回类型解决了本例中的问题,具体如何?@Fureeish将
decltype(auto)
与尾随返回类型对立是错误的。有很多情况下,推导的返回类型不起作用,需要显式返回类型,但没有任何情况下,显式返回类型需要尾部(尽管使用尾部返回类型可能会简化)。还请注意,
decltype(auto)
也可以是尾部返回类型。@VTT如果返回类型依赖于包含函数参数的某个表达式的类型,该怎么办?而且它不包含单个简单的
返回
。或者如果你想要SFINAE?@VTT怎么不?@VTT它仍然是明确的。未命名,但显式。它表示函数具有此特定类型。如果它不依赖于函数参数,而是依赖于其他参数(例如,
a
b
是全局变量),它不会改变任何东西。因此,总结一下,没有绝对必须使用尾部返回类型的情况,对吗?这几乎是我唯一关心的事情(除非答案是否定的-那么我非常感谢一个例子)。@Fureeish:我发现一种情况需要尾部返回类型:lambda,因为我们以前不能有这种类型。但同样与扣减返回类型无关。否则您可以通过更改
Ret
的语法将
auto f()->Ret
转换为
Ret f()
,谢谢。这是我的问题的答案。@ FureeSy:“没有任何情况下,你绝对必须使用尾随返回类型,正确地”在lambdas之外,C++中从未有过“绝对必须使用尾随返回类型”的情况。它总是一个方便的特性,用来减少重复和使代码更清晰。我不确定我是否理解这个问题的要点。假设有人来了,并提供了一些特殊情况,在这种情况下,您既需要显式的返回类型定义,也需要该返回类型的尾部。那是什么意思?这会以任何方式影响人们编码的方式吗?我看不出任何声明是否“过时”有什么意义。@Nicolas我对尾部返回类型的看法有些偏颇,只是函数签名中的
auto
decltype(auto)
。我的印象是,尾部返回类型除了可能引入更可读的语法外,还意味着要解决一些有关返回类型的值类别的问题
decltype(自动)
解决了这个问题。然后我遇到了一些使用尾随返回类型的SFINAE示例,我认为这是必要的(我认为源代码中暗示了这一点)。不管怎样,我发现情况并非如此。那么你对如何改进我的问题有什么建议?
C::iterator C::begin();