Does the equal sign make a difference in brace initialization? eg. ‘T a = {}’ vs ‘T a{}’

The only significant difference I know is in the treatment of explicit constructors: struct foo { explicit foo(int); }; foo f0 {42}; // OK foo f1 = {42}; // not allowed This is similar to the “traditional” initialization: foo f0 (42); // OK foo f1 = 42; // not allowed See [over.match.list]/1. Apart from that, … Read more

What do braces on the left-hand side of a variable declaration mean, such as in T {x} = y?

It’s not a declaration. It’s an assignment to a temporary. In std::unique_ptr<int> {p} = std::make_unique<int>(1);, std::unique_ptr<int> {p} creates a unique_ptr temporary that takes ownership of the object p points to, then std::make_unique<int>(1) is assigned to that temporary, which causes the object p points to to be deleted and the temporary to take ownership of the … Read more

How to initialize an array member in a member initializer list

How can I do what I want to do (that is, initialize an array in a constructor (not assigning elements in the body)). Is it even possible? Yes. It’s using a struct that contains an array. You say you already know about that, but then I don’t understand the question. That way, you do initialize … Read more

Why does the standard differentiate between direct-list-initialization and copy-list-initialization?

Because they don’t do the exact same thing. As stated in 13.3.1.7 [over.match.list]: In copy-list-initialization, if an explicit constructor is chosen, the initialization is ill-formed. In short, you can only use implicit conversion in copy-list-initialization contexts. This was explicitly added to make uniform initialization not, um, uniform. Yeah, I know how stupid that sounds, but … Read more

Why does this code compile (C++11) without a type mismatch error?

You’re not calling vector‘s constructor that takes an initializer_list<char>. That constructor is not viable because, as you said, you’re not passing a list of chars. But vector also has a constructor that takes iterators to a range of elements. template< class InputIt > vector( InputIt first, InputIt last, const Allocator& alloc = Allocator() ); Unfortunately, … Read more

Why do Clang and VS2013 accept moving brace-initialized default arguments, but not GCC 4.8 or 4.9?

Update It appears a fix for the problem has been checked in. Interesting question. It definitely seems to be a bug with how GCC handles = {} initialized default arguments, which was a late addition to the standard. The problem can be reproduced with a pretty simple class in place of std::unordered_map<int,int>: #include <utility> struct … Read more

Has the C++17 extension to aggregate initialization made brace initialization dangerous?

struct D and struct E represent two completely unrelated types. But they’re not “completely unrelated” types. They both have the same base class type. This means that every D is implicitly convertible to a B. And therefore every D is a B. So doing E e{d}; is no different from E e{b}; in terms of … Read more

Why can I not brace initialize a struct derived from another struct?

Answer for C++ standard versions before C++17: Your problem has to do with aggregate initialization: struct X is an aggregate while struct Y is not. Here is the standard quote about aggregates (8.5.1): An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no brace-or-equal-initializers for non-static data members (9.2), … Read more

Deleted default constructor. Objects can still be created… sometimes

When viewing things this way it is easy to say there is complete and utter chaos in the way an object is initialized. The big difference comes from the type of foo: if it is an aggregate type or not. It is an aggregate if it has: no user-provided constructors (a deleted or defaulted function … Read more