C++ 自动退货类型何时适用?
在c++1y中允许自动返回类型的规则是什么C++ 自动退货类型何时适用?,c++,c++14,C++,C++14,在c++1y中允许自动返回类型的规则是什么 #include <iostream> using namespace std; template<typename T1, typename T2> auto f(T1 const& a, T2 const &b) { if (a > b) return a-b; else return a+b; } int main() { cout << f(1, 2.) &
#include <iostream>
using namespace std;
template<typename T1, typename T2>
auto f(T1 const& a, T2 const &b)
{
if (a > b) return a-b;
else return a+b;
}
int main()
{
cout << f(1, 2.) << endl;
return 0;
}
#包括
使用名称空间std;
模板
自动f(T1常数和a、T2常数和b)
{
如果(a>b)返回a-b;
否则返回a+b;
}
int main()
{
库特
函数的圈复杂度有限制吗
身体
标准规定的内容(N3797,§7.1.6.4):
设T
为变量的声明类型或
如果占位符是auto
类型说明符,则
类型是使用模板参数推断规则确定的。如果
该扣减是针对return
语句的,初始值设定项是
括号中的init list(8.5.4)表示程序格式不正确。否则,
通过将出现的auto
替换为新代码,从T
获取P
发明类型模板参数U
或者,如果初始值设定项是
带括号的init list,带有std::initializer\u list
。为
U
使用从函数调用中推断模板参数的规则
(14.8.2.1),其中P
为函数模板参数类型,且
初始值设定项是相应的参数。如果演绎失败,则
声明格式不正确。否则,为
通过将推导的U
替换为
P
因此,tl;dr:返回类型是通过模板参数推断从return
语句中的表达式推断出来的。有一个虚构的模板,它是用return
语句中的表达式作为函数参数调用的,推断出的模板参数U
将替换自动输入占位符返回类型。
现在,如果我们有多个return语句,会发生什么情况?简单:我们为每个return
语句进行推断,并检查它们是否兼容:
如果函数的声明返回类型包含占位符
类型有多个return
语句,返回类型为
每个返回
语句。如果每个
从推论上看,该程序的格式不正确
因此,对于此代码:
template<typename T1, typename T2>
auto f(T1 const& a, T2 const &b)
{
if (a > b) return a-b;
else return a+b;
}
同样,如果推导出的U
s不同,则代码格式不正确
如果您有无返回语句,则根据
如果函数的声明返回类型使用占位符类型
没有return
语句,返回类型是从
一个return
语句,在语句的右括号中没有操作数
功能体
递归
如果您想要递归函数,它会变得更加棘手:
auto f( int a, int b )
{
return a? b + a : f(a-1, b); // This is ill-formed!
}
以下引文解释了该问题:
如果需要具有未减少占位符类型的实体类型
要确定表达式的类型,程序的格式不正确。
但是,一旦在函数中看到return
语句,则
从该语句推导出的返回类型可用于
函数,包括在其他return
语句中
所以我们写:
auto f( int a, int b )
{
if( a )
return b + a;
return f(a-1, b);
}
结论:
您可以使用任意复杂的函数,只要return
语句在演绎过程中都产生相同的类型,并且递归函数在一些非递归的return
-语句之后具有递归调用。如果需要,可以进行强制转换以获得相同的类型。简介
有几个简单的规则说明何时可以从函数体推断函数的返回类型,以及何时auto
可作为返回类型应用
这些规则都在标准()[1]中进行了说明,每一条规则都列在本文剩余部分的相应部分中
[1] 在第7.1.6.4节中,自动说明符[dcl.type.elab]
使用auto
作为返回类型是否有无法推断的内容?
[dcl.type.elab]p1
如果演绎是针对返回
语句的,并且初始值设定项是带括号的初始化列表(8.5.4),则程序格式错误
如果一个函数有多个返回语句,将推断出哪种类型?
[dcl.type.elab]p9
如果具有包含占位符类型的声明返回类型的函数具有多个返回语句,则会为每个返回语句推导返回类型。如果在每个推导中推导的类型不同,则程序的格式不正确
在推导返回类型之前,我可以使用该函数吗?
[dcl.type.elab]p11
如果需要具有未简化占位符类型的实体类型来确定表达式的类型,则程序的格式不正确。但是,一旦在函数中看到返回语句,则从该语句推导出的返回类型可用于函数的其余部分,包括其他返回语句
注意:我们不能将junc
的地址记录在foo
中,因为这样做需要了解junc
的完整类型是什么,在我们提供了返回类型推导的定义之前,我们不知道这一点。(2)因此是合法的,而(1)是不合法的
注意:(3)也是格式不正确的,因为此时我们必须知道递归
的返回类型,但它是未知的。但是,以相反的顺序使用返回语句是有效的。这样编译器就知道递归
要重新编译
auto f( int a, int b )
{
return a? b + a : f(a-1, b); // This is ill-formed!
}
auto f( int a, int b )
{
if( a )
return b + a;
return f(a-1, b);
}
auto func () { return {1,2,3}; } // ill-formed
auto gunc_1 (bool val) { // (1), ill-formed
if (val) return 123;
else return 3.14f;
}
auto gunc_2 (bool val) { // (2), legal
if (val) return static_cast<float> (123);
else return 3.14f;
}
auto hunc () { } // legal, return-type is `void`
auto junc (); // declaration
void foo () { &junc; } // (1), ill-formed
auto junc () { // definition
return 123;
}
void bar () { &junc; } // (2), legal
auto recursive (int x) {
if (--x) return x + recursive (x); // (3), ill-formed
else return 0;
}