Компиляция следующего кода с использованием clang 3.5.0 и gcc 4.9.1 выдает ошибку при последнем утверждении.
#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? <<<
}
Почему Foo({1, 2})
хорошо пока bar({1, 2})
не является?
В частности, было бы здорово узнать об обосновании.
Foo({1,2})
создает временный объект Foo и вызывает конструктор копирования.
Посмотрите этот модифицированный пример с конструктором копирования delete:
http://coliru.stacked-crooked.com/a/6cb80746a8479799
Это ошибки с:
main.cpp:6:5: note: candidate constructor has been explicitly deleted
Foo(const Foo& f) = delete;
Линия
bar({1, 2});
на самом деле проходит в bar
функция, временный объект типа
<brace-enclosed initializer list> // it's made clear in the comments that brace initializers have no type
и нет никакого способа преобразовать этот временный объект в тип первого аргумента, который является int
, Таким образом ошибка
не может конвертировать
<brace-enclosed initializer list>
вint
для аргумента1
в
void bar(int, int)