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

Nik*_*iou 9 c++ language-lawyer c++11 c++14

介绍

在C++ 11中,可以声明一个类似的函数

auto times2(double num) -> double; // A
Run Code Online (Sandbox Code Playgroud)

并定义它

double times2(double num) { // B
    return num*2;
}
Run Code Online (Sandbox Code Playgroud)

这对A, B也可以反过来混合.

C++ 14引入了第三种方式

auto times2(double num) { // C
    return num;
}
Run Code Online (Sandbox Code Playgroud)

Q

  1. 样式C可以在声明/定义对中混合使用吗?A / B
  2. 可以C 单独作为签名(当尚未提供功能的主体时)?

    // waiting for the definition to provide info on return type
    auto times2(double); 
    
    Run Code Online (Sandbox Code Playgroud)

Fil*_*efp 9

混合新旧学校

7.1.6.4p13 auto [dcl.spec.auto]

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

以上报价使它形成不良的混合的.

更具体地说,任何这种混合都会引起歧义,因为两个声明的唯一区别是函数的返回类型 ; 两个声明,其中一个使用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
Run Code Online (Sandbox Code Playgroud)

是一个函数声明使用C++ 14的返回类型推导相当于前向声明吗?

C++ 14中存在与自动返回类型推导相关的规则,该规则指出尚未推导出其返回类型的函数在需要这样的上下文中不可用,这意味着下面的(A)是不等同于旧式宣言(即,在没有定义的情况下可以使用某个功能).

auto foobar (double); // (A)

int main () {
  auto ret = foobar(3.14f); // ill-formed, return type is not known (yet)
}

...
Run Code Online (Sandbox Code Playgroud)

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
}
Run Code Online (Sandbox Code Playgroud)

barbaz我们foobar实际实例化之前barbaz,我们必须不知道返回类型,但如果没有前向声明,auto foobar(T)我们就无法在模板中引用这样的名称.

  • @BryanChen在这个琐碎的例子中肯定会有可能,但是如果`foobar`的定义依赖于`barbaz`怎么办?比如在这个[愚蠢的例子](http://coliru.stacked-crooked.com/a/33c2aacfd4967fc9). (2认同)