Initialization difference with or without Curly braces in C++11

后端 未结 3 1311
野性不改
野性不改 2020-11-29 23:22

We can initialize the variable in two ways in C++11

One:

int abc = 7;

Two:

int ab         


        
3条回答
  •  一向
    一向 (楼主)
    2020-11-29 23:54

    Short version

    Initialization via {..} is list-initialization, which prohibits narrowing conversions. For example, if LLONG_MAX is the maximum value of an long long int, and your int cannot represent that:

    int x = LLONG_MAX;  // probably accepted with a warning
    int x {LLONG_MAX};  // error
    

    Similarly:

    long long y = /*something*/;
    
    int x = y;  // accepted, maybe with a warning
    int x {y};  // error
    

    Long version

    An initialization of the form

    T x = a;
    

    is copy-initialization; an initialization of either form

    T x(a);
    T x{a};
    

    is direct-initialization, [dcl.init]/15-16.

    [dcl.init]/14 then says:

    The form of initialization (using parentheses or =) is generally insignificant, but does matter when the initializer or the entity being initialized has a class type; see below.

    So for non-class types, the form of the initialization doesn't matter. However, there's a difference between these two direct-initializations:

    T x(a);  // 1
    T x{a};  // 2
    

    and similarly, between these two copy-initializations:

    T x = a;    // 1
    T x = {a};  // 2
    

    Namely, the ones with {..} use list-initialization. The {..} is called a braced-init-list.

    So, when you compare T x = a; to T x {a};, there are two differences: copy- vs. direct-initialization, and "non-list-" vs. list-initialization. As already mentioned by others and in the quote above, for non-class types T, there's no difference between copy- and direct-init. However, there's a difference between list-init and no list-init. That is, we could as well compare

    int x (a);
    int x {a};
    

    List-initialization in this case prohibits narrowing conversions. Narrowing conversions are defined in [dcl.init.list]/7 as:

    A narrowing conversion is an implicit conversion

    • from a floating-point type to an integer type, or

    • from long double to double or float, or from double to float, except where the source is a constant expression and the actual value after conversion is within the range of values that can be represented (even if it cannot be represented exactly), or

    • from an integer type or unscoped enumeration type to a floating-point type, except where the source is a constant expression and the actual value after conversion will fit into the target type and will produce the original value when converted back to the original type, or

    • from an integer type or unscoped enumeration type to an integer type that cannot represent all the values of the original type, except where the source is a constant expression whose value after integral promotions will fit into the target type.

提交回复
热议问题