Cpp11 列表初始化

LIZHAO Modern Cpp
阅读量 0 评论量 0

从花括号初始化器列表初始化对象

直接列表初始化

语法

直接列表初始化
T object { arg1, arg2, ... };	
T { arg1, arg2, ... }	
new T { arg1, arg2, ... }	
Class { T member { arg1, arg2, ... }; };
Class::Class() : member{arg1, arg2, ...} {...}//在构造函数的成员初始化列表中,若使用花括号初始化器列表

实例

class T {
public:
    vector<int> veca;
    vector<int> vecb;
    vector<int> vecc;
	//不能有自定义的构造函数。
};


class B {
    T t{{1, 2}, {2, 3}, {3, 4}};
};


int main() {
    T t{ {1, 2}, {2, 3}, {3, 4} };

    auto t1 = T{ {1, 2}, {2, 3}, {3, 4} };
    auto *p = new T{ {1, 2}, {2, 3}, {3, 4} };

    return 0;
}

复制列表初始化

复制列表初始化
T object = {arg1, arg2, ...};	//赋值运算
function( { arg1, arg2, ... } )	 //函数参数
return { arg1, arg2, ... } ;	 //函数返回值
object[ { arg1, arg2, ... } ]	//在具有用户定义的 operator[] 的下标表达式中,以列表初始化对重载运算符的形参初始化
object = { arg1, arg2, ... }		
U( { arg1, arg2, ... } )	
Class { T member = { arg1, arg2, ... }; };	 // 在使用等号的非静态数据成员初始化器中

列表初始化规则

聚合类型可直接列表初始化。

聚合类型

  1. 普通数组
      –  char chs[10], int ints[10]

  2.   – 没有自定义构造函数– 没有私有或被保护的成员–  没有基类–  没有虚函数–  没有{}=直接初始化的非静态数据成员

代码实例

#include <iostream>
#include <vector>
#include <map>
#include <string>
 
struct Foo {
    std::vector<int> mem = {1,2,3}; // 非静态成员的列表初始化
    std::vector<int> mem2;
    Foo() : mem2{-1, -2, -3} {} // 构造函数中的成员列表初始化
};
 
std::pair<std::string, std::string> f(std::pair<std::string, std::string> p)
{
    return {p.second, p.first}; // return 语句中的列表初始化
}
 
int main()
{
    int n0{};     // 值初始化(为零)
    int n1{1};    // 直接列表初始化
    std::string s1{'a', 'b', 'c', 'd'}; // initializer_list 构造函数调用
    std::string s2{s1, 2, 2};           // 常规构造函数调用
    std::string s3{0x61, 'a'}; // initializer_list 构造函数偏好 (int, char)
 
    int n2 = {1}; // 复制列表初始化
    double d = double{1.2}; // 纯右值的列表初始化,然后复制初始化
    auto s4 = std::string{"HelloWorld"}; // 同上, C++17 起不创建临时对象
 
    std::map<int, std::string> m = { // 嵌套列表初始化
           {1, "a"},
           {2, {'a', 'b', 'c'} },
           {3, s1}
    };
 
    std::cout << f({"hello", "world"}).first // 函数调用中的列表初始化
              << '\n';
 
    const int (&ar)[2] = {1,2}; // 绑定左值引用到临时数组
    int&& r1 = {1}; // 绑定右值引用到临时 int
//  int& r2 = {2}; // 错误:不能绑定右值到非 const 左值引用
 
//  int bad{1.0}; // 错误:窄化转换
    unsigned char uc1{10}; // 可以
//  unsigned char uc2{-1}; // 错误:窄化转换
 
    Foo f;
 
    std::cout << n0 << ' ' << n1 << ' ' << n2 << '\n'
              << s1 << ' ' << s2 << ' ' << s3 << '\n';
    for(auto p: m)
        std::cout << p.first << ' ' << p.second << '\n';
    for(auto n: f.mem)
        std::cout << n << ' ';
    for(auto n: f.mem2)
        std::cout << n << ' ';
}
喵~