Исполняемые продуцируемые лязгом 3.5.0 и GCC 4.9.1 из кодаПочему Foo ({}) вызывает Foo (0) вместо Foo()?
#include <iostream>
struct Foo
{
Foo() { std::cout << "Foo()" << std::endl; }
Foo(int x) { std::cout << "Foo(int = " << x << ")" << std::endl; }
Foo(int x, int y) { std::cout << "Foo(int = " << x << ", int = " << y << ")" << std::endl; }
};
int main() // Output
{ // ---------------------
auto a = Foo(); // Foo()
auto b = Foo(1); // Foo(int = 1)
auto c = Foo(2, 3); // Foo(int = 2, int = 3)
auto d = Foo{}; // Foo()
auto e = Foo{1}; // Foo(int = 1)
auto f = Foo{2, 3}; // Foo(int = 2, int = 3)
auto g = Foo({}); // Foo(int = 0) <<< Why?
auto h = Foo({1}); // Foo(int = 1)
auto i = Foo({2, 3}); // Foo(int = 2, int = 3)
}
ведут себя, как прокомментировал.
От cppreference: cpp/language/list initialization:
[...] T({ arg1, arg2, ... }) (7) [...]
Эффекты инициализации списка объекта типа Т являются:
Если
T
представляет собой агрегат типа, совокупная инициализация выполняется.В противном случае, если список бит-init пуст, а
T
- тип класса с конструктором по умолчанию, выполняется инициализация значения.[...]
Я пришел к выводу, что Foo({})
должен вызывать конструктор по умолчанию.
Где ошибка?
Ошибка указана в cppreference. – Casey
Исправлено cppreference, чтобы прочитать «Эффекты инициализации списка объекта типа« T »из * не скобки в скобках-init-list * are ...» были бы яснее? – Casey
@ Casey Я бы сказал нет. И сказал бы, что 'T ({...})' is * not * инициализация списка объекта типа 'T', а не добавлять неопределенные формулировки, которые могут быть неверно истолкованы. Cpprefrerence уже не утверждает, что это так. Но с вашим предложенным исправлением он будет читать, что 'T ({...})' - это инициализация списка объекта типа 'T' из скопированного списка инициализации в скобках, который не является * случаем. Это инициализация списка любого параметра, который имеет выбранный конструктор. –