c++11之統(tǒng)一初始化(Uniform Initalization)實現
一. 變量初始化
int a = 1;、int b(2); 兩種寫法,無統(tǒng)一標準
// 主函數:程序執(zhí)行的起點(必須有且僅有一個)
int main() {
// 基本類型:統(tǒng)一用 {},支持省略等號
int a{1}; // 等價于 int a = 1;
double b{3.14}; // 無隱式類型轉換(如寫 b{3} 沒問題,但 b{3.14f} 也沒問題,嚴格來說是窄化轉換被禁止)
std::cout << "Hello GCC! 這是C++主程序" << std::endl; // 控制臺輸出內容
return 0; // 程序正常退出(返回0表示成功)
}
二. 數組初始化
int arr[] = {1,2,3};` 對于聚合對象有區(qū)別
// main.cpp:C++ 主程序入口
#include <iostream> // 包含輸入輸出流庫(cout 所需)
struct teacher {
int id; // 成員1:編號
const char* name; // 成員2:姓名
int age; // 成員3:年齡
};
// 主函數:程序執(zhí)行的起點(必須有且僅有一個)
int main() {
// 驗證1:單個對象的聚合初始化(C++11+支持,C++03不支持)
teacher t1 = {101, "Zhang San", 35}; // 等號可選
teacher t2{102, "Li Si", 40}; // C++11+ 允許省略等號(列表初始化)
// 驗證2:數組的聚合初始化(直接用成員值,而非已創(chuàng)建對象)(C++11+支持,C++03不支持)
teacher arr[] = {
{103, "Wang Wu", 38}, // 直接初始化數組第1個元素
{104, "Zhao Liu", 42} // 直接初始化數組第2個元素
};
std::cout << "Hello GCC! 這是C++主程序" << std::endl; // 控制臺輸出內容
return 0; // 程序正常退出(返回0表示成功)
}
- g++ main.cpp -o test -std=c++03 方式編譯會報錯
- g++ main.cpp -o test -std=c++11 方式編譯不會報錯
三. 容器初始化
vector<int> v; v.push_back(1); v.push_back(2); 繁瑣,不能直接批量賦值;
// C++98 代碼
#include <vector>
using namespace std;
int main() {
vector<int> v; // 空容器
v.push_back(1); // 第1個元素
v.push_back(2); // 第2個元素
v.push_back(3); // 第3個元素
// 若要初始化10個元素,需寫10行push_back,極其冗余
return 0;
}
C++98 甚至不支持 vector<int> v = {1,2,3}; 這種直觀寫法,唯一的「批量初始化」 workaround 是用數組臨時中轉,但更繁瑣:
// C++98 勉強實現批量初始化(不推薦)
int temp[] = {1,2,3};
vector<int> v(temp, temp + sizeof(temp)/sizeof(temp[0])); // 借助迭代器范圍
在c++11標準下,支持以下方式:
// C++11 代碼
#include <vector>
#include <map>
#include <list>
using namespace std;
int main() {
// 1. vector 直接批量初始化(像數組一樣簡潔)
vector<int> v{1,2,3,4,5}; // 等價于 v = {1,2,3,4,5},支持等號可選
vector<string> strs{"apple", "banana", "orange"}; // 字符串容器也支持
// 2. 其他容器同樣支持
list<int> lst{10,20,30}; // 鏈表
map<string, int> score{
{"Zhang", 90},
{"Li", 85},
{"Wang", 95} // map 的鍵值對批量初始化,直觀清晰
};
// 3. 嵌套容器初始化(復雜場景也支持)
vector<vector<int>> matrix{
{1,2,3},
{4,5,6},
{7,8,9} // 二維vector直接初始化,無需多層push_back
};
return 0;
}
代碼可讀性直接拉滿,一眼就能看出容器的初始內容,徹底告別冗余的 push_back。
C++11 容器的 {} 初始化會直接根據 initializer_list 中的元素個數,一次性分配足夠的內存,避免了多次擴容和元素拷貝:
- 比如 vector<int> v{1,2,3,4,5},容器會先計算出需要存儲 5 個元素,直接分配能容納 5 個 int 的內存,再把元素拷貝進去(僅一次拷貝);
- 而 C++98 的 push_back 可能需要 2-3 次擴容(比如初始容量 1→2→4→8,最后容量 8,浪費空間且有多次拷貝)。
四. 窄化轉換風險
double x = 3.14; int y = x;(double→int 丟失精度,C++98 僅警告,不報錯);
int main() {
// 測試1:C++98 允許的窄化轉換(C++11 {} 禁止)
int a{3.14}; // 窄化轉換:編譯錯誤(C++11)
// 測試2:顯式轉換后允許(C++11)
int b = static_cast<int>(3.14); // 顯式聲明,編譯通過
cout << "b = " << b << endl;
return 0;
}
- g++ main.cpp -o test -std=c++03 編譯只有警告,但是能編譯通過
- g++ main.cpp -o test -std=c++11 編譯報錯
五. 初始化歧義
vector<int> v(10);(10 個默認值 0)和 vector<int> v{10};(1 個元素 10),C++98 無區(qū)分方式
僅支持圓括號 () 初始化:vector<int> v(10) 的行為和 C++11 一致(創(chuàng)建 10 個默認值為 0 的元素)
不支持花括號 {} 初始化: vector<int> v{10} 在 C++98 中是 語法錯誤,編譯器無法識別花括號作為初始化列表的語法。
int main() {
std::vector<int> v1(10);
std::cout << "v1 使用 (10) 初始化:" << std::endl;
std::cout << " 大小: " << v1.size() << std::endl;
std::vector<int> v2{10};
std::cout << "v2 使用 {10} 初始化:" << std::endl;
std::cout << " 大小: " << v2.size() << std::endl;
// C++98 中,圓括號 () 的行為和 C++11 一樣
// C++98 中,沒有列表初始化語法,花括號 {} 不能這樣用
// std::vector<int> v98_2{10}; // 編譯錯誤!C++98 不認識這種語法。
return 0;
}
g++ main.cpp -std=c++03
使用c++03編譯的時候,會有報錯
root@DFH-X5-243030:/mnt/d/linux_path/study# g++ main.cpp -std=c++03
main.cpp: In function ‘int main()':
main.cpp:15:24: warning: extended initializer lists only available with ‘-std=c++11' or ‘-std=gnu++11' [-Wc++11-extensions]
15 | std::vector<int> v2{10};
| ^
main.cpp:15:22: error: in C++98 ‘v2' must be initialized by constructor, not by ‘{...}'
15 | std::vector<int> v2{10};
| ^~
root@DFH-X5-243030:/mnt/d/linux_path/study#
使用c++11編譯正常,打印結果如下:
root@DFH-X5-243030:/mnt/d/linux_path/study# g++ main.cpp -std=c++11
root@DFH-X5-243030:/mnt/d/linux_path/study# ll
total 32
drwxrwxrwx 1 gupan gupan 4096 Nov 21 11:13 ./
drwxrwxrwx 1 gupan gupan 4096 Nov 11 17:35 ../
-rwxrwxrwx 1 gupan gupan 25160 Nov 21 11:13 a.out*
-rwxrwxrwx 1 gupan gupan 803 Nov 21 11:13 main.cpp*
root@DFH-X5-243030:/mnt/d/linux_path/study# ./a.out
v1 使用 (10) 初始化:
大小: 10
v2 使用 {10} 初始化:
大小: 1
root@DFH-X5-243030:/mnt/d/linux_path/study#
到此這篇關于c++11之統(tǒng)一初始化(Uniform Initalization)實現的文章就介紹到這了,更多相關c++11 統(tǒng)一初始化內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

