不那么新的C++标准学习笔记 logo 不那么新的C++标准学习笔记

编译器支持最低版本要求:

  • GCC: 4.4(v1.0)
  • MSVC: 16.0(v0.9)
  • Clang: Yes

提案: N1984(v1.0)

自动类型推导是降低编码负担的一种手段,在其他编程语言比如Go中也有类似的功能。C++11修改了关键字auto原有的作用,使其为自动类型推导所用。在C++11之前,template就已经具有类型推导能力,而C++11中增加的auto通常情况下就是使用template的类型推导方式:

int main(int argc, char *argv[]) 
{
  auto x = 17; // x = int
  auto& y = x; // y = int&
  const auto& i = x; // i = const int&
  auto z = y; // z = int
  const auto f = y; // f = const int
  auto& m = i; // m = const int&
  auto&& t = i; // t = int&
  auto&& t1 = 10; // t1 = int&& 
  return 0;
}
int main(int argc, char *argv[]) 
{
  int A[3] = {1, 2, 3};
  auto a = A; // a = int *
  auto& a1 = A; // a1 = int (&)[3]
  return 0;
}

还有了新式的函数声明形式:

auto get_fun(int arg) -> double (*)(double) // same as: double (*get_fun(int))(double)
{
    switch (arg)
    {
        case 1: return std::fabs;
        case 2: return std::sin;
        default: return std::cos;
    }
}

auto代替了声明变量时的强制类型信息如intint&const int&int&&等等,但是在使用auto时:

  1. 必须初始化变量,当然好的编码实践即使不用auto也会要求声明变量时立即初始化
  2. 函数返回值不能是auto(仅C++11而言,C++14中已经修改
  3. 函数的形参类型不能是auto,即使指定了默认参数也不行(仅C++11而言,C++14中lambda表达式部分已经修改
  4. auto不能声明为模板的参数(仅C++11而言?)
  5. 非静态成员变量不能是auto的,即使指定了初始值也不行
  6. 不能声明auto数组

另外,由于C++11新增了初始化列表功能,使用auto自动推导出来的类型可能会有出乎意料的情况:

int main(int argc, char *argv[]) 
{
  int a0 = (1); // a0 = int
  auto a1 = (1); // a1 = int
  int a2 = {1}; // a0 = int
  auto a3 = {1}; // a3 = std::initializer_list<int>
  return 0;
}

a1如愿得到int类型,而a3却跟a2是不同的类型,因为初始化列表拥有特有的类型std::initializer_list<int>

一般而言,在以下场合使用auto比较合适:

  1. 类型名比较长,比如std::vector<std::string>::iteratorstd::shared_ptr<std::vector>等等诸如此类的要声明变量可以使用auto

  2. 类型名比较难书写,比如临时定义一个lambda表达式,又要把它保存到一个变量中以便之后调用,就可以用auto

    auto f = [&](int n)->int { return n+1; };
    auto i = f(10);
    
  3. Scott Meyers《Effective Modern C++》中提议优先使用auto,这也许是一种趋势。

相关链接

感觉不错,小额赞助一下!

Hosted by Coding Pages, 本站由 @missdeer 创建,由 Jekyll 于 2018-03-01 生成,感谢 CloudCannon 制作的theme: Edition ,感谢 Let's Encrypt 提供免费的SSL证书服务。本站点采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。© 2018