Why does the init-list bit behave differently in a function call compared to a constructor call?

Compiling the following code with clang 3.5.0 and gcc 4.9.1 results in an error in the last statement.

#include <iostream> struct Foo { Foo(int x, int y) { std::cout << "Foo(int = " << x << ", int = " << y << ")" << std::endl; } }; void bar(int x, int y) { std::cout << "bar(int = " << x << ", int = " << y << ")" << std::endl; } int main() { Foo({}, {}); // Foo(int = 0, int = 0) Foo({1}, {2}); // Foo(int = 1, int = 2) Foo({1, 2}); // Foo(int = 1, int = 2) bar({}, {}); // bar(int = 0, int = 0) bar({1}, {2}); // bar(int = 1, int = 2) bar({1, 2}); // error: no matching function for call to 'bar' <<< Why? <<< } 

Why is Foo({1, 2}) ok and bar({1, 2}) not?

In particular, it would be great to know about the rationale.

+5
source share
2 answers

Foo({1,2}) creates a temporary Foo object and calls the copy constructor.

See this modified example with the delete copy constructor: http://coliru.stacked-crooked.com/a/6cb80746a8479799

These are errors with:

 main.cpp:6:5: note: candidate constructor has been explicitly deleted Foo(const Foo& f) = delete; 
+6
source

Line

 bar({1, 2}); 

actually goes into the bar function, a temporary object of type

 <brace-enclosed initializer list> // it made clear in the comments that brace initializers have no type 

and there is no way to convert this temporary object to the type of the first argument, which is int . So the error

cannot convert <brace-enclosed initializer list> to int for argument 1 to

 void bar(int, int) 
+1
source

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


All Articles