龙空技术网

C++14语言特性之六:函数返回类型推导和decltype(auto)

骇客遇见AI 248

前言:

眼前大家对“c语言函数的返回类型可以是double吗”大致比较珍视,你们都想要学习一些“c语言函数的返回类型可以是double吗”的相关内容。那么小编在网摘上收集了一些关于“c语言函数的返回类型可以是double吗””的相关文章,希望朋友们能喜欢,大家一起来学习一下吧!

Language Feature

Proposal

Available in GCC?

SD-6 Feature Test

Return type deduction for normal functions

N3638

4.8 (N3386)

4.9 (N3638)

__cpp_decltype_auto >= 201304

没出现在C++11中的原因

任何C++用户在了解了C++ 11的auto、lambds和置返回类型的特性后,都会立刻想知道为什么不能在函数声明中写入auto并推导返回类型。这个功能之前在N2954中提出过,但由于时间限制从C++ 11中删除了,因为草案没有解决核心工作组提出的各种问题和担忧。我现在已经在GCC中实现了这个功能,并建议将其添加到C++ 14中。

C++14扩展

C++11允许lambda函数根据return语句的表达式类型推断返回类型。

C++14为普通的函数也提供了这个能力。C++14还拓展了原有的规则,使得函数体并不是{return expression;}形式的函数也可以使用返回类型推导。为了启用返回类型推导,函数声明必须将auto作为返回类型,但没有C++11的后置返回类型说明符。如果函数实现中含有多个return语句,这些表达式必须可以推断为相同的类型。这样的函数中可以存在递归,但递归调用必须在函数定义中的至少一个return语句之后。C++14增加了decltype(auto)的语法。允许auto的类型声明使用decltype的规则。也即,允许不必显式指定作为decltype参数的表达式,而使用decltype对于给定表达式的推断规则。decltype(auto)的语法也可以用于返回类型推导,只需用decltype(auto)代替auto。禁止虚函数使用auto用于返回类型推导禁止返回类型推导使用initializer-list

auto f() { return {10} ;}
如果使用返回类型推导,则不能使用返回类型SFINAE函数不被推导为noexcept前置声明和重复声明例子

C++11前置声明:

#include <iostream>struct A {  auto f()->int; // forward declaration};auto A::f() -> int { return 42; }  int  main(int argc, char* argv[]){    A a;    std::cout << a.f() << std::endl;    return 0;}
 g++ -std=c++11  -o n3638 n3638.cpp./n363842

C++14前置声明:

#include <iostream>struct A {  auto f(); // forward declaration};auto A::f() { return 42; }  int  main(int argc, char* argv[]){    A a;    std::cout << a.f() << std::endl;    return 0;}
g++ -std=c++14  -o n3638 n3638.cpp ./n363842

重复声明:

#include <iostream>auto f(); // return type is unknownauto f() { return 42; } // return type is intauto f(); // redeclaration//int  f(); // error,  ambiguating new declaration of ‘int f()’  int  main(int argc, char* argv[]){    std::cout << f() << std::endl;    return 0;}

模板:

#include <iostream>template <class T> auto g(T t); // forward declarationtemplate <class T> auto g(T t) { return t; } // return type is deduced at instantiation timetemplate <class T> auto g(T t); // redeclaration  template <class T> auto f(T t) { return t; } // #1template auto f(int); // OK//template char f(char); // error: template-id ‘f<>’ for ‘char f(char)’ does not match any template declarationtemplate<> auto f(double); // OK, forward declaration with unknown return type//template <class T> T f(T t) { return t; } // OK, not functionally equivalent to #1  int  main(int argc, char* argv[]){    std::cout << g(1) << std::endl;    std::cout << f(2) << std::endl;    return 0;}
多个return语句例子
#include <iostream>auto iterate(int len){  for (int i = 0; i < len; ++i)    if (i == 3)      return i;  return -1;}  int  main(int argc, char* argv[]){    std::cout << iterate(10) << std::endl;    return 0;}
递归调用例子
#include <iostream>auto sum(int i) {  if (i == 1)    return i;          // return type deduced to int  else    return sum(i-1)+i; // ok to call it now}int  main(int argc, char* argv[]){    std::cout << sum(10) << std::endl;    return 0;}
实例化例子

即使不使用odr,也需要实例化自动函数模板。

#include <iostream>template <class T> auto f(T t) { return t; } // return type deduced at instantiation timetypedef decltype(f(1)) fint_t; // must instantiate f<int> to deduce return typeint  main(int argc, char* argv[]){    fint_t ff = 10;    std::cout << ff << std::endl;    return 0;}
后置返回类型中使用auto例子
#include <iostream>struct A { static int t; };auto& f() { return A::t; } // returns by referenceint A::t = 10;int  main(int argc, char* argv[]){    auto v = []()->auto& { return f(); }();    std::cout << v << std::endl;    return 0;}
使用额外的未使用的模板参数来执行SFINAE例子
#include <iostream>template <class T, class U>auto min1(T x, U y){ return x < y ? x : y; }template <class T, class U,          class...,          class = std::enable_if_t<std::is_integral< T >::value &&                                   std::is_integral<U>::value>>auto min2(T x, U y){    return x < y ? x : y;}int  main(int argc, char* argv[]){    struct foo {};    //min1(foo{}, foo{}); // error - invalid operands to <    min1(10, 20);    //min2(foo{}, foo{}); // error - no matching function min2    min2(10, 20);    return 0;}
decltype(auto) 例子
#include <iostream>int echo(const char *a, const char *b){    std::cout << a << " " << b <<  std::endl;    return 2;}template<class Fun, class... Args>decltype(auto) Call(Fun fun, Args&&... args) {     return fun(std::forward<Args>(args)...); }int  main(int argc, char* argv[]){    Call(echo, "hello","world");    return 0;}

标签: #c语言函数的返回类型可以是double吗