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<typename T1, typename T2>

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

  return x + y;

}

// C++14:

template<typename T1, typename T2>

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<typename T, typename I>

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

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

  std::vector<int> v = {0};

  accessVector(v, 0) = 10000;

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

  return 0;

}

5、做Perfect Forwarding 中對{}表達式的中轉

void foo(std::vector<int> v) {

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

}

template<typename ...Arg>

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

  foo(std::forward<Arg...>(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<bool> v ={ true };

  auto x = v.at(0);  // std::vector<bool>::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<int>;

}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章