简体   繁体   中英

Trailing comma in uniform initialization

Is there any potential semantic difference when I use trailing comma during uniform initialization?

std::vector< std::size_t > v1{5, }; // allowed syntax
std::vector< std::size_t > v2{10};

Can I use trailing comma to make compiler to select std::vector::vector(std::initializer_list< std::size_t >) constructor instead of std::vector::vector(std::size_t, const std::size_t &) or are there any other tricks with mentioned syntax?

Can I use it to detect is there std::initializer_list -constructor overloading?

Considering the following code, which constructor must be selected?

struct A { A(int) { ; } A(double, int = 3) { ; } };
A a{1};
A b{2, };

This code is accepted by gcc 8 and A(int) is selected in both cases.

First, The C++ grammar rules makes the trailing , optional for braced-init-list . To quote dcl.init/1

A declarator can specify an initial value for the identifier being declared. The identifier designates a variable being initialized. The process of initialization described in the remainder of [dcl.init] applies also to initializations specified by other syntactic contexts, such as the initialization of function parameters ([expr.call]) or the initialization of return values ([stmt.return]).

 initializer: brace-or-equal-initializer ( expression-list ) brace-or-equal-initializer: = initializer-clause braced-init-list initializer-clause: assignment-expression braced-init-list braced-init-list: { initializer-list ,opt } { designated-initializer-list ,opt } { } 

Secondly, you can't pretty much override the overload resolution system. It will always use the std::initializer_list constructor if you use such syntax and such std::initializer_list constructor is available.

dcl.init.list/2 :

A constructor is an initializer-list constructor if its first parameter is of type std​::​initializer_list or reference to possibly cv-qualified std​::​initializer_list for some type E, and either there are no other parameters or else all other parameters have default arguments. [ Note: Initializer-list constructors are favored over other constructors in list-initialization ([over.match.list])....


The program below prints Using InitList :

#include <iostream>
#include <initializer_list>

struct X{
    X(std::initializer_list<double>){ std::cout << "Using InitList\n"; }
    X(int){ std::cout << "Using Single Arg ctor\n"; }
};

int main(){
    X x{5};
}

Despite the fact that 5 is a literal of type int , it should have made sense to select the single argument constructor since its a perfect match; and the std::initializer_list<double> constructor wants a list of double . However, the rules favour std::initializer_list<double> because its an initializer-list constructor .

As a result, even the program below fails because of narrowing conversion:

#include <iostream>
#include <initializer_list>

struct Y{
    Y(std::initializer_list<char>){ std::cout << "Y Using InitList\n"; }
    Y(int, int=4){ std::cout << "Y Using Double Arg ctor\n"; }
};

int main(){
    Y y1{4777};
    Y y2{577,};
    Y y3{57,7777};
}

In response to your comment below, " what if there is no overloading with std::initializer_list, or it is not the first constructor's parameter? " - then overload resolution doesn't choose it. Demo:

#include <iostream>
#include <initializer_list>

struct Y{
    Y(int, std::initializer_list<double>){ std::cout << "Y Using InitList\n"; }
    Y(int, int=4){ std::cout << "Y Using Double Arg ctor\n"; }
};

int main(){
    Y y1{4};
    Y y2{5,};
    Y y3{5,7};
}

Prints:

Y Using Double Arg ctor
Y Using Double Arg ctor
Y Using Double Arg ctor

If there is no initializer-list constructor available, then the {initializer-list...,} initializer pretty much falls back to direct initialization as per dcl.init/16 , whose semantics are covered by the proceeding paragraph of dcl.init/16

No. That comma is a concession to make preprocessor macro tricks work without compile errors. It means nothing about your data type or its size.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM