为什么列表初始化(使用大括号)比其他方法更好? 基本上从Bjarne Stroustrup的《C++程序设计语言第四版》中复制粘贴粘贴:

为什么列表初始化(使用大括号)比其他方法更好? 基本上从Bjarne Stroustrup的《C++程序设计语言第四版》中复制粘贴粘贴:,c++,c++11,syntax,initialization,list-initialization,C++,C++11,Syntax,Initialization,List Initialization,列表初始化不允许缩小范围(§iso.8.5.4)。即: 整数不能转换为另一个不能保存其值的整数。例如,char 允许使用到int,但不允许int到char 无法将浮点值转换为另一个无法保存其值的浮点类型 价值例如,允许浮动到双精度,但不允许双精度浮动 浮点值不能转换为整型 整数值不能转换为浮点类型 例如: MyClass a1 {a}; // clearer and less error-prone than the other three MyClass a2 = {a}; MyC

列表初始化不允许缩小范围(§iso.8.5.4)。即:

  • 整数不能转换为另一个不能保存其值的整数。例如,char 允许使用到int,但不允许int到char
  • 无法将浮点值转换为另一个无法保存其值的浮点类型 价值例如,允许浮动到双精度,但不允许双精度浮动
  • 浮点值不能转换为整型
  • 整数值不能转换为浮点类型
例如:

MyClass a1 {a};     // clearer and less error-prone than the other three
MyClass a2 = {a};
MyClass a3 = a;
MyClass a4(a);
void fun(double val, int val2) {

    int x2 = val;    // if val == 7.9, x2 becomes 7 (bad)

    char c2 = val2;  // if val2 == 1025, c2 becomes 1 (bad)

    int x3 {val};    // error: possible truncation (good)

    char c3 {val2};  // error: possible narrowing (good)

    char c4 {24};    // OK: 24 can be represented exactly as a char (good)

    char c5 {264};   // error (assuming 8-bit chars): 264 cannot be 
                     // represented as a char (good)

    int x4 {2.0};    // error: no double to int value conversion (good)

}

=优先于{}的唯一情况是使用
auto
关键字获取初始值设定项确定的类型

例如:

MyClass a1 {a};     // clearer and less error-prone than the other three
MyClass a2 = {a};
MyClass a3 = a;
MyClass a4(a);
void fun(double val, int val2) {

    int x2 = val;    // if val == 7.9, x2 becomes 7 (bad)

    char c2 = val2;  // if val2 == 1025, c2 becomes 1 (bad)

    int x3 {val};    // error: possible truncation (good)

    char c3 {val2};  // error: possible narrowing (good)

    char c4 {24};    // OK: 24 can be represented exactly as a char (good)

    char c5 {264};   // error (assuming 8-bit chars): 264 cannot be 
                     // represented as a char (good)

    int x4 {2.0};    // error: no double to int value conversion (good)

}
auto z1{99};//z1是一个整数
自动z2={99};//z2是std::初始值设定项列表
自动z3=99;//z3是一个整数

结论

<强>首选{ }初始化,除非有很强的理由不.< /强>

基本上从Bjarne Stroustrup的“C++程序设计语言第四版”中复制和粘贴:

列表初始化不允许缩小范围(§iso.8.5.4)。即:

  • 整数不能转换为另一个不能保存其值的整数。例如,char 允许使用到int,但不允许int到char
  • 无法将浮点值转换为另一个无法保存其值的浮点类型 价值例如,允许浮动到双精度,但不允许双精度浮动
  • 浮点值不能转换为整型
  • 整数值不能转换为浮点类型
例如:

MyClass a1 {a};     // clearer and less error-prone than the other three
MyClass a2 = {a};
MyClass a3 = a;
MyClass a4(a);
void fun(double val, int val2) {

    int x2 = val;    // if val == 7.9, x2 becomes 7 (bad)

    char c2 = val2;  // if val2 == 1025, c2 becomes 1 (bad)

    int x3 {val};    // error: possible truncation (good)

    char c3 {val2};  // error: possible narrowing (good)

    char c4 {24};    // OK: 24 can be represented exactly as a char (good)

    char c5 {264};   // error (assuming 8-bit chars): 264 cannot be 
                     // represented as a char (good)

    int x4 {2.0};    // error: no double to int value conversion (good)

}

=优先于{}的唯一情况是使用
auto
关键字获取初始值设定项确定的类型

例如:

MyClass a1 {a};     // clearer and less error-prone than the other three
MyClass a2 = {a};
MyClass a3 = a;
MyClass a4(a);
void fun(double val, int val2) {

    int x2 = val;    // if val == 7.9, x2 becomes 7 (bad)

    char c2 = val2;  // if val2 == 1025, c2 becomes 1 (bad)

    int x3 {val};    // error: possible truncation (good)

    char c3 {val2};  // error: possible narrowing (good)

    char c4 {24};    // OK: 24 can be represented exactly as a char (good)

    char c5 {264};   // error (assuming 8-bit chars): 264 cannot be 
                     // represented as a char (good)

    int x4 {2.0};    // error: no double to int value conversion (good)

}
auto z1{99};//z1是一个整数
自动z2={99};//z2是std::初始值设定项列表
自动z3=99;//z3是一个整数

结论
首选{}初始化而非替代方法,除非您有充分的理由不这样做。

使用大括号初始化有很多原因,但您应该注意,首选
初始值设定项列表
构造函数而非其他构造函数
,默认构造函数除外。这会导致构造函数和模板出现问题,其中类型
T
构造函数可以是初始值设定项列表,也可以是普通的旧构造函数

auto z1 {99};   // z1 is an int
auto z2 = {99}; // z2 is std::initializer_list<int>
auto z3 = 99;   // z3 is an int
structfoo{
Foo(){}
Foo(标准::初始值设定项列表){

std::cout使用大括号初始化有很多原因,但是您应该知道与其他构造函数相比,
初始值设定项列表
构造函数更受欢迎,默认构造函数除外。这会导致构造函数和模板出现问题,其中类型可以是
T
构造函数她是一个初始化列表或一个普通的老ctor

auto z1 {99};   // z1 is an int
auto z2 = {99}; // z2 is std::initializer_list<int>
auto z3 = 99;   // z3 is an int
structfoo{
Foo(){}
Foo(标准::初始值设定项列表){

std::cout关于使用列表初始化的优点已经有了很好的答案,但是我个人的经验法则不是尽可能地使用大括号,而是让它依赖于概念含义:

  • 如果我在概念上创建的对象包含我在构造函数中传递的值(例如容器、POD结构、原子、智能指针等),那么我使用大括号
  • 如果构造函数类似于普通函数调用(它执行一些由参数参数化的或多或少复杂的操作),那么我使用的是普通函数调用语法
  • 对于默认初始化,我总是使用大括号。
    首先,通过这种方式,我始终确保对象得到初始化,而不管它是一个带有默认构造函数的“真实”类(无论如何都会被调用)还是一个内置的/POD类型。其次,在大多数情况下,它与第一条规则一致,因为默认初始化对象通常表示一个“空”对象
根据我的经验,这个规则集可以比默认情况下使用大括号更加一致地应用,但是必须明确记住所有异常,当它们不能使用或与带括号的“正常”函数调用语法(调用不同的重载)有不同的含义时

例如,它非常适合标准库类型,如
std::vector

struct Foo {
    Foo() {}

    Foo(std::initializer_list<Foo>) {
        std::cout << "initializer list" << std::endl;
    }

    Foo(const Foo&) {
        std::cout << "copy ctor" << std::endl;
    }
};

int main() {
    Foo a;
    Foo b(a); // copy ctor
    Foo c{a}; // copy ctor (init. list element) + initializer list!!!
}
vector a{10,20};//大括号->用参数填充向量
向量b(10,20);//括号->使用参数对某些功能进行参数化,
向量c(it1,it2);//类似于用10个整数填充向量或复制一个范围。
向量d{};//空大括号->默认构造向量,这是等效的
//到填充了零元素的向量

关于使用列表初始化的优点,已经有了很好的答案,但是我个人的经验法则是,尽可能不使用大括号,而是根据概念含义来确定:

  • 如果我在概念上创建的对象包含我在构造函数中传递的值(例如容器、POD结构、原子、智能指针等),那么我使用大括号
  • 如果构造函数类似于普通函数调用(它执行一些由参数参数化的或多或少复杂的操作),那么我使用的是普通函数调用语法
  • 对于默认初始化,我总是使用大括号。
    首先,通过这种方式,我始终确保对象得到初始化,而不管它是一个带有默认构造函数的“真实”类(无论如何都会被调用)还是一个内置的/POD类型