Help me sort out the meaning of “{}” as a constructor argument
scottmeyers.blogspot.com
Help me sort out the meaning of “{}” as a constructor argument
1–10 of 181 posts
Re: Help me sort out the meaning of “{}” as a constructor argument
#2X{{}};
will:
for T = DefCtor call the initializer_list constructor with a single default constructed element. The outer brakets are for the initalizer list and the inner ones are for the DefCtor constructor. The brackets for T constructor itself are allowed to be elided.
for T = NoDefCtor, the previous overload resolution is not valid as NoDefCtor has its default constructor disabled, so the inner brackets match an empty initializer_list, while the outer ones the X constructor.
finally, for T = DeletedDefCtor one would expect the same as NoDefCtor, but there is a quirk in the language: explicitly disabling the default constructor still allows aggregate initialization (which is enabled for any class that doesn't have otherwise a constructor); this allows for the same overload resolution as in DefCtor. This is considered a defect and will be hopefully corrected soon.
While initializer_list allows for some nice syntactic sugar, I think it is now generally considered to be misdesigned, especially as it breaks the otherwise great uniform initialization syntax ({..}) that was added at the same time in C++11. There is an ongoing effort to fix the it, but it is hard to do without breaking backward compatibility.
edit: formatting
Re: Help me sort out the meaning of “{}” as a constructor argument
#3The answer to the problem can be found in the comments, but not in a single place: X {{}}; will: for T = DefCtor call the initializer_list constructor with a single default constructed element. The outer brakets are for the initalizer list and the inner ones are for the DefCtor constructor. The brackets for T constructor itself are allowed to be elided. for T = NoDefCtor, the previous overload resolution is not valid…
Re: Help me sort out the meaning of “{}” as a constructor argument
#4The answer to the problem can be found in the comments, but not in a single place: X {{}}; will: for T = DefCtor call the initializer_list constructor with a single default constructed element. The outer brakets are for the initalizer list and the inner ones are for the DefCtor constructor. The brackets for T constructor itself are allowed to be elided. for T = NoDefCtor, the previous overload resolution is not valid…
My god c++ is atrocious.
Between moving from MS to POSIX environments in the 90s, and the "death" of Borland, this left me with few options other than another Faustian deal with Java-land, alas.
I'm actually liking Javascript nowadays, though. Especially as more of an FP-capable language than an OOP-mandatory language.
Re: Help me sort out the meaning of “{}” as a constructor argument
#5Was there ever a Goldilocks moment when C was just right?
Re: Help me sort out the meaning of “{}” as a constructor argument
#6The answer to the problem can be found in the comments, but not in a single place: X {{}}; will: for T = DefCtor call the initializer_list constructor with a single default constructed element. The outer brakets are for the initalizer list and the inner ones are for the DefCtor constructor. The brackets for T constructor itself are allowed to be elided. for T = NoDefCtor, the previous overload resolution is not valid…
T(initializer_list);
Before, if you did T element;
T list = {element};
the second initialization would be dispatched to the initializer_list constructor; after the fix (for GCC, after 4.9) it would call the copy constructor. See http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html... .For us, this changed the semantics of folly::dynamic, which used the initializer_list constructor to construct lists:
dynamic element = "hello";
dynamic list = {element}; // ["hello"] before, "hello" after
We had to deprecate the initializer_list constructor and fix all the occurrences (https://github.com/facebook/folly/commit/07dc3ce5923b2d761ca..., https://github.com/facebook/folly/commit/d458b0a14486b9d80d5...).Re: Help me sort out the meaning of “{}” as a constructor argument
#7The answer to the problem can be found in the comments, but not in a single place: X {{}}; will: for T = DefCtor call the initializer_list constructor with a single default constructed element. The outer brakets are for the initalizer list and the inner ones are for the DefCtor constructor. The brackets for T constructor itself are allowed to be elided. for T = NoDefCtor, the previous overload resolution is not valid…
My god c++ is atrocious.
... ok, even I can't say that with a straight face.
Re: Help me sort out the meaning of “{}” as a constructor argument
#8The answer to the problem can be found in the comments, but not in a single place: X {{}}; will: for T = DefCtor call the initializer_list constructor with a single default constructed element. The outer brakets are for the initalizer list and the inner ones are for the DefCtor constructor. The brackets for T constructor itself are allowed to be elided. for T = NoDefCtor, the previous overload resolution is not valid…
My god c++ is atrocious.
Re: Help me sort out the meaning of “{}” as a constructor argument
#9It seems to me C/C++ has always had problems. K&R C had weird stuff like char pointers used to point to anything. And modern C++ has odd complexities like what Scott's article illustrates. Was there ever a Goldilocks moment when C was just right ?
Based on things like the shell tools and languages like awk (and other related descendants), I don't think even the unix creators meant for much application level work to be done in C, though, but by assembling components in higher level languages. Try telling that to The Management and all the macho/masochistic Real Programmers, though. Bounds checking? Memory management? (names you can identify to the left of the types, like in Algol, instead of to the right?) That's for sissies!
Re: Help me sort out the meaning of “{}” as a constructor argument
#10The answer to the problem can be found in the comments, but not in a single place: X {{}}; will: for T = DefCtor call the initializer_list constructor with a single default constructed element. The outer brakets are for the initalizer list and the inner ones are for the DefCtor constructor. The brackets for T constructor itself are allowed to be elided. for T = NoDefCtor, the previous overload resolution is not valid…
A similar defect that was "fixed" breaking backward compatibility was the resolution of initializer_list constructors of recursive types: T(initializer_list ); Before, if you did T element; T list = {element}; the second initialization would be dispatched to the initializer_list constructor; after the fix (for GCC, after 4.9) it would call the copy constructor. See http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defe…
[hi ot, long time no see]