Implicit type conversion from an initialization list compiles in one case, but not in another

I defined the following class:

class A {
    int a;
public:
    A(int _a = 0) :a(_a){}
    A(initializer_list<int> il) :a(il.size()){}
    friend A operator+(const A& a1, const A& a2);
};
A operator+(const A& a1, const A& a2){ return A(); }

The following customer code

A a;
operator+(a,{3, 4, 5});

may compile but the following

A a;
a + {3, 4, 5};

cannot compile. Error message " error C2059: syntax error : '{'" and " error C2143: syntax error : missing ';' before '{'".

Both two client codes try to perform implicit type conversion from the initialization list {3,4,5}to class A, but the first is executed while the second fragment does not work. I do not understand why.

Can you explain this?

I am using MS Visual Studio 2013 4 update.

[] , . , : , -init-list RHS , . , , , arg1 + arg2, operator+ (arg1, arg2), arg1 . , . , , , - , , . , . , , , - ++? , .

+4
2

, clang, :

error: initializer list cannot be used on the right hand side of operator '+'

++ 11, (8.5.4/1 [dcl.init.list]):

.

  • (8.5)
  • (5.3.4)
  • return (6.6.3)
  • (5.2.2)
  • (5.2.1)
  • (8.5, 5.2.3)
  • (9.2)
  • mem-initializer (12.6.2)
  • (5.17)

, , braced-init-list , . operator+(a, {1, 2, 3}) - 4. a = {1, 2, 3} - . a + {1, 2, 3} . .

+3

, , expression + braced-init-list, , , -

§5.1.2 (4)

-init-list

. :

postfix-expression:
    simple-type-specifier braced-init-list
    typename-specifier braced-init-list

, +, , , expression + braced-init-list ++-.

-init-list, initializer:

assignment-expression:
    logical-or-expression assignment-operator initializer-clause
initializer-clause:
    assignment-expression
    braced-init-list

, + =:

A operator+=(A& a1, const A& a2){ return A(); }
int main() {
    A a;
    a + A{3, 4, 5};
    a += {3, 4, 5};
}
0

Source: https://habr.com/ru/post/1584603/


All Articles