在 C++11 中,可以声明类似的函数
auto times2(double num) -> double; // A
并将其定义为
double times2(double num) { // B
return num*2;
}
这对
A, B
也可以相反地混合。
C++14引入了第三种方式
auto times2(double num) { // C
return num;
}
C
可以与A / B
在声明/定义对中混合吗?
可以
C
独立作为签名(当函数体尚未提供时)?
// waiting for the definition to provide info on return type
auto times2(double);
7.1.6.4p13
说明符auto
[dcl.spec.auto]
使用占位符类型声明返回类型的函数或函数模板的重新声明或特化也应使用该占位符,而不是推导类型。
上述引用使得将 new 与 old 混合在一起的格式不正确。
更具体地说,任何此类混合都会引入歧义,因为两个声明中的唯一区别是函数的“返回类型”;换句话说,两个声明,其中一个使用 auto
,另一个使用非推导类型
T
,并不引用同一个函数。auto f ();
auto f () { return 123; } // legal, return type is `int`
auto g ();
auto g () -> int; // ill-formed, an invalid overload of `g` introduced
int h ();
auto h (); // ill-formed, an invalid overload of `h` introduced
使用 C++14 返回类型推导的函数声明是否等同于前向声明?中存在与自动返回类型推导相关的规则,其中规定尚未推导其返回类型的函数在需要此类推导的上下文中不可用,这意味着下面的 (A) 并不等同于老式声明(即可以在没有定义的情况下使用函数)。
auto foobar (double); // (A)
int main () {
auto ret = foobar(3.14f); // ill-formed, return type is not known (yet)
}
...
您是说返回类型为7.1.6.4p9
auto
说明符[dcl.spec.auto]
如果需要具有未推导的占位符类型的实体的类型来确定表达式的类型,则程序格式错误。...
auto
template<class T>
auto foobar (T);
template<class T>
auto barbaz (T val) { return foobar (val); }
template<class T>
auto foobar (T val) { return val * 2; }
int main () {
barbaz (1234); // return-type is int
barbaz (3.1f); // return-tupe is float
}
在
barbaz
内部无法知道
foobar
的返回类型,直到我们实际实例化barbaz
,但是如果没有auto foobar(T)
的前向声明,我们无法在模板中引用这样的名称。