C++ 中,auto 关键字

在函数返回值/range-for 等情况中

1auto使用 5种用法

     auto :拷贝

     auto& :左值引用,只能接左值(和常量右值)

     auto&& :万能引用,能接左值和右值

     const auto& :const 万能引用,能接左值和右值

     const auto&& :常量右值引用,只能接右值

很多人直接就写成 auto&&,但尽量分场景使用

    auto:用于你想修改右值的情形

    auto&:用于你想修改左值的情形

    auto&&:用于泛型编程中的转发

    const auto&:用于只读

    const auto&&:基本没用,基本可被 const auto& 替代(比 const auto& 多一个语义:一定得是右值。然而这没什么用,因为你都不对其进行修改,是左还是右没什么影响)

2、返回值自动推导,增强模板的泛型能力

//C++11

template

auto sum(T1&& x, T2&& y) -> decltype(x + y) {

  return x + y;

}

// C++14:

template

auto sum(T1&& x, T2&& y) {

  return x + y;

}

3、泛型Lambda

// C++14;

auto mul = [](const auto x, const auto y) { return x * y; };

4decltypeauto)推导保留cv:

// C++14;

template

decltype(auto) accessVector(T&& c, I i) { return c[i]; }  // 返回 int&;

int main(int argc, char** argv) {

  std::vector v = {0};

  accessVector(v, 0) = 10000;

  std::cout << v.at(0) << std::endl;  // 10000;

  return 0;

}

5、做Perfect Forwarding 中对{}表达式的中转

void foo(std::vector v) {

  for (const auto& i : v) { std::cout << i << std::endl; }

}

template

void forwardFunc(Arg&& ...args) {

  foo(std::forward(args...));

}

int main(int argc, char** argv) {

  auto il = {1, 2, 3};

  forwardFunc(il);

  return 0;   

}

6、简化函数指针写法

int(*(*foo)())() {};
auto
foo() -> auto (*)() -> int(*)() {};  // 与上述等价;

需要注意的几个坑

1、STL 代理类型导致 auto 可能推导出并非自己想要的类型:

// 主要源于 std::vector 在存储布尔元素时的特殊方式;

int main(int argc, char** argv) {

  std::vector v ={ true };

  auto x = v.at(0);  // std::vector::reference, not bool;

  return 0;

}

2、auto 在推导 List Initialization 表达式时的默认类型(std::initializer_list)

int main(int argc, char** argv) {

  auto l = {1, 2, 3};  // std::initializer_list;

}

 

 

你可能感兴趣的:(C++11)