1.c++中指定初始化值的方式有4種方式:(1)小括號 int x(0);(
2)等號 int x = 0;(
3)大括號 int x;
(4)等號和大括號 int x = ;
2.c++11統一初始化, 即使用大括號初始化方式, 其使用場景主要有以下3種:(1
)類非靜態成員指定預設值
(2)為容器賦值 vector vec = ;
(3)對不支援拷貝操作的物件賦值 unique_ptrp{};
之所以稱為統一初始化, 其原因在於上述3種使用場景中, 第(1
)種不支援小括號;第(2
)種不支援等號和小括號;第(3
)種不支援等號.
3.統一初始化的優勢:
(1)能禁止內建型別之間的隱式窄化轉換, 即表示式無法保證接收物件能夠表達其值, 則**不能通過編譯(至少會給出編譯警告)!如
double d{}; longx;(
2)可以有效解決小括號定義物件卻解析為宣告函式的問題.
如 int
x(); 宣告為函式 x 而不是定義變數, 使用統一初始化則不會出現問題.
4.統一初始化的不足:
不足之處在於過載匹配過程變得更加複雜, 難於理解:(1
)對過載函式, 統一初始化使用大括號會將資料宣告為 initializer_list 物件,
只有過載匹配過程中, 無法找到 initializer_list型別的形參時, 其它函式才會成為可選函式.
因此, 對宣告了 initializer_list 形參的過載函式, 則使用統一初始化的**會優先匹配該函式, 而其他更精確匹配的版本可能沒有機會被匹配.
其中需要特別注意的是經常使用容器 vector.
如 vector
vec(10, 2) 和 vector vec, 前者是含有 10 個元素的物件, 而後者是只包含 10 和 2
兩個元素的物件.(2
)對於建構函式, 空大括號構造乙個物件時, 不是匹配 initializer_list 形參的版本, 而是預設建構函式.
class
test
template
test(std::initializer_list
ls)
};進行如下呼叫時,
test t1{};
test t2;
//test t3};
//error: no matching function for call to 'test::test(
)' test t4};
test t5({});
其中 t1 和 t5 使用預設建構函式, t2 和 t4 使用列表初始化建構函式, t3 則不能定義.(3
)對於 initializer_list 模板特例化版本, 情形較第2種又有所不同.
a. void foo(int
); b. template
void foo(initializer_listlsi);
當進行以下函式呼叫 foo(
0); foo({}); foo(); 時, 分別呼叫的是 a, a, b.
c. void foo(int
); d.
void foo(initializer_listlsi);
當進行以下函式呼叫 foo(
0); foo({}); foo(); 時, 分別呼叫的是 c, d, d.
C 統一初始化語法(列表初始化)
不格 要是世上不曾存在c 14和c 17該有多好!constexpr是好東西,但是讓編譯器開發者痛不欲生 新標準庫的確好用,但改語法細節未必是明智之舉,尤其是3年一次的頻繁改動。c 帶了太多歷史包袱,我們都是為之買賬的一員。我沒那麼多精力考慮c 14 17的問題,所以本文基於c 11標準。知其所以然...
c 11 統一的初始化和初始化列表
在c 11以前,程式設計師,或者初學者經常會感到疑惑關於怎樣去初始化乙個變數或者是乙個物件。初始化經常使用括號,或者是使用大括號,或者是復賦值操作。因為這個原因,c 11提出了統一初始化,以為著使用這初始化列表,下面的做法都是正確的。int value std vectorvi std vector...
C 基礎一初始化
include include using namespace std 單行 注釋 多行注釋 常量定義 define month 12 define day 31 main為c 的入口函式 int main 變數定義 char b b int a 10 const int hours 24 cons...