1. 程式人生 > >C++ 初始化

C++ 初始化

body public 復雜 pan tty 比較 類型 ali bsp

考慮如下代碼:

int main(){
     int x = 1;
     //int y = (1); //無用
     int z = { 1 };
     
     int a;  //沒有初始化器,不考慮
     int b(1);
     int c{ 1 };
 }

眼花繚亂的初始化語法。帶初始化器的,基本就是:=1 (1) ={1} 或 {1} 這幾種情況。變量名字和初始化器的分隔符是:= () {}這三種

#include <iostream>

class S {
public:
    S(std::initializer_list<int
> il) { std::cout << "S(std::initializer_list<int> il) called" << std::endl; } S(int i) { std::cout << "S(int i) called" << std::endl; } }; int main(){ S y = 1; S z = { 1 }; S a(1); S b{ 1 }; }

我們發現,對於用戶定義類型,具有{} 初始化器的,優先匹配S(std::initializer_list<int> il)。這給人提了個醒,{}不是那麽萬能的初始化語法。如果想調用S(int)這個構造函數,還是要老實的用傳統的S a(1)語法。

#include <boost/type_index.hpp> 
#include <iostream>

int main()
{
    auto x = (1);
    auto y = 1;
    auto z = { 1 };
    auto a(1);
    auto b{ 1 };

    using boost::typeindex::type_id_with_cvr;

    std::cout << type_id_with_cvr< decltype(x)>().pretty_name() << 
\n; std::cout << type_id_with_cvr< decltype(y)>().pretty_name() << \n; std::cout << type_id_with_cvr< decltype(z)>().pretty_name() << \n; std::cout << type_id_with_cvr< decltype(a)>().pretty_name() << \n; std::cout << type_id_with_cvr< decltype(b)>().pretty_name() << \n; }

auto使用另外的規則,={1} 會推導成std::initializer_list<int>{1} 而{1}會推導成 (int)1

總結:基本類型int: ={1} {1} 推導成 (int)1

自定義類型: ={1} {1} 推導成std::initializer_list<int>{1} 註:前提是自定義類型構造函數有std::initializer_list為參數的構造函數,就像S定義的那樣。

auto的情況: ={1} 推導成std::initializer_list<int>{1}

{1} 推導成(int)1

規則還是比較復雜難記的,所以遇到{}初始化器還是小心為妙。

C++ 初始化