Live data from Hacker News

Help me sort out the meaning of “{}” as a constructor argument

scottmeyers.blogspot.com

1–10 of 181 posts

Re: Help me sort out the meaning of “{}” as a constructor argument

#2
The 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 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

#3

The 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

#4

The 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.

Like "Wargames", the best way to win is not to play.

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

#5
It 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?

Re: Help me sort out the meaning of “{}” as a constructor argument

#6

The 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_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

#7

The 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.

please, if you had 10 years of experience in the language, read every article on C++11/14/17, followed closely the evolution of the language, the answer would have been obvious...

... ok, even I can't say that with a straight face.

Re: Help me sort out the meaning of “{}” as a constructor argument

#8

The 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.

C++ is hard. If one sticks to a strict subset it is a nice language. The problem is the code one didn't write. Even the STL is ugly to use. They are trying to fix the language by adding features but it's like Javascript, the old ugly ones are still part of the spec.

Re: Help me sort out the meaning of “{}” as a constructor argument

#9

It 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 ?

C works great, as an alternate to assembler, to bootstrap unix up on meager, 80s style, hardware.

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

#10
post #6

The 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…

And that fix is still far from fixing the language. I had tought that deprecating brace elision for initializer_list and always requiring double braces would be a workable, although backward incompatible fix, but it still cause issues. There was a recent thread on the topic on std-discussion recently.

[hi ot, long time no see]

Post reply on HN