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();
[]()->某些类型{/*…*/}
(相当于[]()->自动{/*…*/}
)[](){/*…*/}
[]()->decltype(自动){/*…*/}
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();