Search code examples
c++functionconstructorc++14list-initialization

Why does braced-init-list behave differently in a function call versus a constructor invocation?


Compiling the following code with clang 3.5.0 and gcc 4.9.1 yields an error at 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}) okay while bar({1, 2}) is not?

Particularly, it would be great to learn about the rationale.


Solution

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

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

    It errors with:

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