在前向声明中自动推导返回类型并与旧函数语法混合

问题描述 投票:0回答:1

简介

在 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;
}

  1. 样式
    C
    可以与A / B
    声明/定义
    对中混合吗?
  2. 可以

    C
    独立作为签名(当函数体尚未提供时)?

    // waiting for the definition to provide info on return type
    auto times2(double); 
    
c++ c++11 language-lawyer c++14
1个回答
11
投票

混合新派和旧派

7.1.6.4p13
auto
说明符
[dcl.spec.auto]

使用占位符类型声明返回类型的函数或函数模板的重新声明或特化也应使用该占位符,而不是推导类型。

上述引用使得将 newold 混合在一起的格式不正确。

更具体地说,任何此类混合都会引入歧义,因为两个声明中的唯一区别是函数的“返回类型”;换句话说,两个声明,其中一个使用 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 返回类型推导的函数声明是否等同于前向声明?

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)
的前向声明,我们无法在模板中引用这样的名称。
    

© www.soinside.com 2019 - 2024. All rights reserved.