Ad N
Ad N

Reputation: 8376

Why are explicit constructors not matching when list-initializing function arguments?

To illustrate the issue, let's consider those two simple definitions, Bar being a user type with explicit constructor from int:

struct Bar
{
    explicit Bar(int a)
    {}
};

void f(Bar)
{}

Now, as cppreference states:

direct-list-initialization (both explicit and non-explicit constructors are considered)

We can initialize an instance this way

Bar b1{5};

Yet, this is a compilation error to call the function this way

f({5});

It would still naively look like direct list initialization of the Bar argument of f, plus one could argue that explicitely using braces around the argument makes it... explicit.

What is the rationale for disallowing usage of the explicit constructor for list-initialized function arguments ?

Edit

The linked page is indeed saying that this is not direct-list-initialization in this situation. Yet, in the spirit of the question, what would be the rationale to design the language rules so this case is a copy-list-init rather than a direct-list-init ?

Upvotes: 1

Views: 139

Answers (1)

songyuanyao
songyuanyao

Reputation: 172864

Because for passing function argument, it's not direct-list-initialization, but copy-list-initialization; only non-explicit constructors may be called.

function( { arg1, arg2, ... } ) ; (7) 
  • copy-list-initialization (only non-explicit constructors may be called)

7) in a function call expression, with braced-init-list used as an argument and list-initialization initializes the function parameter

Note that before C++11 (i.e. in spite of the C++11 feature list initialization), passing an argument to a function by value is always regarged as copy initialization, not direct initialization.

Upvotes: 1

Related Questions