這裡介紹 C++ 語言的 auto
自動變數類型的用法,並提供幾種使用範例程式碼。
在 C++14 標準跟前一版的 C++11 比較起來沒有太大的變革,大概都是改善舊的語法,讓程式設計者更方便使用,這裡我將介紹 auto
這個 C++11 所新增的自動變數類型,以及在 C++14 中的變革。
auto
自動變數類型
在 C++11 標準下,對於有被明確初始化的變數,我們可以使用 auto
這個新的變數類型,讓編譯器自動判斷其變數的類型,例如:
#include <cmath> int main() { // 等同於 int x = 1; auto x = 1; // 等同於 double y = sin(1.3); auto y = sin(1.3); return 0; }
使用 gcc 4.9 編譯 C++11 的程式碼時,要加上 -std=c++11
:
g++-4.9 -std=c++11 source.cpp
使用 gcc 6.3 編譯時就不需要加任何參數:
/usr/local/gcc-6.3.0/bin/g++ source.cpp
auto
變數實際的型別是在編譯時期進行判定的,在真正執行時就跟一般的 C++ 型別一樣,所以不會造成額外的負擔。
由於 auto
是根據變數的資料來判斷實際的型別,所以若是僅使用 auto
宣告變數,但未定義變數的內容,就會產生錯誤:
// 錯誤 auto z;
在 C++11 的標準中,auto
不可以用於函數的傳回值,但後來 C++14 的標準加入了這個用法:
// 在 C++11 中無法使用,但 C++14 則可以 auto my_fun() { int value = 3; return value; } int main() { my_fun(); return 0; }
編譯器會依照函數的傳回值來決定 auto
實際對應的變數型別。
而這段原始碼在編譯時就要使用 C++14 的標準才行,若用 gcc 4.9 編譯則必須加上 -std=c++14
:
g++-4.9 -std=c++14 source.cpp
而 gcc 6.3 則不需要任何參數:
/usr/local/gcc-6.3.0/bin/g++ source.cpp
C++98、C++11 與 C++14 範例比較
這是一段使用 C++98 標準的 C++ 程式碼,程式碼比較冗長:
#include <iostream> #include <vector> // 將每個數值加上 1 std::vector<int>& addOne(std::vector<int> &v) { for(std::vector<int>::iterator it = v.begin(); it != v.end(); it++) { *it += 1; } return v; } int main() { // C++98 的 std::vector 初始化寫法 static const int arr[] = {12, -3, 6, 19}; std::vector<int> x (arr, arr + sizeof(arr) / sizeof(arr[0]) ); std::vector<int> y = addOne(x); for (std::vector<int>::const_iterator i = y.begin(); i != y.end(); ++i) { std::cout << *i << ' '; } std::cout << std::endl; return 0; }
整個程式的邏輯很簡單,一開始定義了一個 addOne
函數,它的作用就是把一個整數向量中的每個值都加 1
,而主程式中我們定義了一個 x
向量,將其傳給 addOne
處理之後,指定給 y
向量,最後用一個迴圈將 y
輸出。
從 C++11 開始我們可以使用以範圍為基礎的 for 迴圈,加上 auto
語法後,可將程式碼改寫為:
#include <iostream> #include <vector> std::vector<int>& addOne(std::vector<int> &v) { for(auto& it : v) { it += 1; } return v; } int main() { // C++11 的 std::vector 初始化寫法 std::vector<int> x = {12, -3, 6, 19}; auto y = addOne(x); for (auto& it : y) { std::cout << it << ' '; } std::cout << std::endl; return 0; }
而在 C++14 之後,函數的傳回值也可以使用 auto
:
auto& addOne(std::vector<int> &v) { for(auto& it : v) { it += 1; } return v; }
g++ 4.9.1 以後的編譯器甚至還有支援這種泛型函數(generic function)的寫法:
auto& addOne(auto &v) { for(auto& it : v) { it += 1; } return v; }
這樣的寫法適用於各種數值向量。
參考資料:Solarian Programmer、StackOverflow