Executables produced by clang 3.5.0 and gcc 4.9.1 from the code
#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)
}
behave as commented.
From cppreference: cpp/language/list initialization:
[...] T( { arg1, arg2, ... } ) (7) [...]
The effects of list initialization of an object of type T are:
If
T
is an aggregate type, aggregate initialization is performed.Otherwise, If the braced-init-list is empty and
T
is a class type with a default constructor, value-initialization is performed.[...]
I concluded that Foo({})
should call the default constructor.
Where's the bug?
T
from a non-parenthesized braced-init-list are..." would that have been clearer? – ArdyceT({...})
is not a list initialization of an object of typeT
, rather than to add vague wording that could be misinterpreted. Cpprefrerence already doesn't claim it to be. But with your proposed fix, it would read thatT({...})
is a list initialization of an object of typeT
from a parenthesized braced init list, which is not the case. It is a list initialization of whatever parameter the chosen constructor has. – PubilisT({...}, {...}, ...)
(aswell as in the function case and whereever multiple lists make sense. just as done witharg1, arg2 ...
). Then it can't be confused as a list initialization of an object of typeT
so easily anymore, I think. – PubilisT({args...})
is list-initialization. It was listed (pun intended) on the "list-initialization" page as alternative 7 of the situations in which list-initialization is performed. I think the OP's reading of the page was accurate. The proper fix may be to remove items 5, 6, and 7 from the page altogether. – ArdyceT
. And indeed the page does not claim that it is. Just as it doesn't claim that alternative 5 initializes a function (perhaps more obvious here). – PubilisT({...})
byU({...})
to avoid the problem with the text referring toT
, which here is not right. – PubilisFoo({2, 3})
invokesFoo(int, int)
. – Shahaptian