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

时间:2014-06-09 07:18:06

标签: c++ c++11 language-lawyer c++14

简介

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

Q

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

    C

1 个答案:

答案 0 :(得分:9)

混合新旧学校

  

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

     
    

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

  

以上引文将 new 混合在一起格式不正确。

更具体地说,任何这样的混合引入了歧义,因为两个声明的唯一区别是函数的 return-type ;一个使用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)的前向声明我们就不能在我们的模板中引用这样的名称。