在c 1y中允许 writing自动返回类型的规则是什么?
#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; }
函数体的圈复杂度是否存在限制?
解决方法
有一些简单的规则可以说明何时可以从函数体中推导出函数的返回类型,以及当auto适用于返回类型时.
这些规则都在标准(n3797)[1]中说明,并且每个规则在本文其余部分的自己的部分中列出.
[1],第7.1.6.4节,自动说明符[dcl.type.elab].
是否有任何使用auto作为返回类型无法推断出来的?
[dcl.type.elab]p1
If the deduction is for areturn
statement and the initializer is a braced-init-list (8.5.4),the program is ill-formed.
auto func () { return {1,2,3}; } // ill-formed
如果函数有多个return语句,将推导出哪种类型?
[dcl.type.elab]p9
If a function with a declared return type that contains a placeholder type has multiple return statements,the return type is deduced for each return statement. If the type deduced is not the same in each deduction,the program is 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; }
注意:(1)格式错误,因为所有的return语句都不是同一类型,而(2)是合法的,因为两个return语句产生相同的类型.
如果函数没有return语句会发生什么?
[dcl.type.elab]p10
If a function with a declared return type that uses a placeholder type has no return statements,the return type is deduced as though from a return statement with no operand at the closing brace of the function body.
auto hunc () { } // legal,return-type is `void`
在推断出返回类型之前,我可以使用该函数吗?
[dcl.type.elab]p11
If the type of an entity with an undeduced placeholder type is needed to determine the type of an expression,the program is ill-formed. Once a return statement has been seen in a function,however,the return type deduced from that statement can be used in the rest of the function,including in other return statements.
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; }
注意:我们不能在foo中获取junc的地址,因为这样做需要知道junc的完整类型是什么,直到我们提供了推断返回类型的定义之后才知道的东西. (2)因此是合法的,而(1)则不是.
注意:(3)也是格式不正确的,因为我们必须知道此时递归的返回类型,但它是未知的.但是,以相反的顺序使返回语句有效.这样编译器会知道递归,当它返回x recursive(x)时返回int.