
Help me sort out the meaning of “{}” as a constructor argument - signa11
http://scottmeyers.blogspot.com/2016/11/help-me-sort-out-meaning-of-as.html
======
gpderetta
The answer to the problem can be found in the comments, but not in a single
place:

X<T>{{}};

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

~~~
shmageggy
My god c++ is atrocious.

~~~
Roboprog
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.

~~~
yoodenvranx
I miss Delphi, it was awesome for rapid GUI development :(

~~~
alyandon
You can check out the cross-platform OSS equivalent if you are feeling
particularly nostalgic!

[http://www.lazarus-ide.org/](http://www.lazarus-ide.org/)

------
seanwilson
C++ FAQs are full of massively complex conundrums like this for problems you
just don't get in other languages. I used to love learning all these highly
specific C++ rules and playing language lawyer when I didn't know any better
and thought it was a good use of learning time to become an expert. I've since
moved on to languages that weren't full of problems like this that let you
just get on with what you're meant to be making. If Scott Meyers can't figure
this one out what hope would anyone else?

~~~
munificent
> I've since moved on to languages that weren't full of problems like this

I think you mean _aren 't_ full of those problems _yet_. :)

There's a lot of nasty corners in C++ but almost all of them are because it
effectively has 40 years of wild success. (I say 40 because C++ inherits C's
baggage and success.)

It's totally reasonable to pick a younger language with fewer warts. Become an
expert in it! Be productive! Ship lots of apps.

Then, one day, decades and several versions hence, you may find yourself now
dealing with all of the warts that language has accrued over time. At this
point, you're too invested in it to jump ship. The marginal cost of learning a
new corner case is smaller than the cost to start over from scratch and learn
2046's new hot language.

Alas, expertise is hard. Everything you learn makes you better at X but
slightly disincentivizes you to learn Y, which may not even exist yet.

~~~
seanwilson
> Then, one day, decades and several versions hence, you may find yourself now
> dealing with all of the warts that language has accrued over time.

What languages are getting even close to being as bad as C++ in this respect
though? Java, Python and JavaScript have been around for a while now for
example and they seem more opinionated in a way that stops too many warts from
appearing.

C++ has undefined and compiler dependent behaviour in the core of its design
which I think is the real problem. Its complexity just multiplies at an
exponential rate as more features and undefined behaviour is introduced.

~~~
sqeaky
Most languages have Undefined and Implementation specific behavior. Few
languages have so carefully specified their undefined behavior as C++ though.

~~~
kazinator
Undefined behavior is _not_ specified, by definition! It is the absence of
requirements, including the requirements to diagnose.

C++ has something called "unspecified behavior" also, which is stronger than
undefined, because it gives requirements. It denotes some circumstances when
an implementation can behave in one of a finite possible ways (none of which
fail) and must choose one of them without documenting which choice is made.
For instance the expression f(a(), b(), c()) can call the functions a, b and c
in any of the six possible permutations of the order: no particular order is
specified. (This arises due to the order of evaluation of function arguments
being unspecified, together with the sequenced evaluation of function calls.)

The specifications of C and C++ contain large number of places in which they
carefully state that no requirements apply to some situation. This is not a
good thing; it's basically a myriad holes punched in the requirement spec, any
one of which could be a pitfall.

Few languages are so chock full of holes in their requirements.

~~~
paulddraper
> Undefined behavior is not specified

> unspecified is stronger than undefined because it gives requirements.

I do not understand what you are saying.

~~~
kazinator
"unspecified behavior" in C++ is a formal term denoting a situation in which
requirements are in fact given. There are multiple possible requirements, and
the implementation chooses which apply, without having to document the choice.
So in fact something is specified, just not entirely.

"undefined behavior" refers to situations in which no requirements apply at
all. (Truly unspecified in the regular sense of the word.)

~~~
paulddraper
Thanks, I understand your usage now.

Unspecified means the implementation has some leeway.

Undefined means the implementation can do anything.

~~~
kazinator
Yes; as in "unspecified _which choice_ ".

------
DoofusOfDeath
I've been programming professionally for over 20 years, most of it in C++. I
really like developing fast code, and C++ used to be my favorite tool for the
job.

But the language complexity gets more insane with every revision. It's now at
the point where Scott Freakin' Meyers can't figure out the interpretation of a
short little chunk of code.

I'm now actively looking for gigs in which I can develop high-performance code
in a language _other than_ C++, just because it's such a minefield.

I don't follow the discussions of the standards committee carefully, but it
seems like they must place almost no premium on keeping the language (and its
programs) understandable by non-language-lawyers.

~~~
johan_larson
Any sense of where the C++ refugees are heading?

Rust? Go?

~~~
bnastic
"C with classes". (I'm not joking)

~~~
bitL
The most reasonable choice, restricting yourself to a subset. I knew C++ lost
it when people started writing library code resembling monads.

~~~
johan_larson
"When your template system turns out to be Turing-complete, you may have gone
too far."

------
johan_larson
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_?

~~~
Roboprog
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!

~~~
pjmlp
Worse is that even the C creators saw the danger of using C without computer
assisted validation and created lint in 1979.

[https://www.bell-labs.com/usr/dmr/www/chist.html](https://www.bell-
labs.com/usr/dmr/www/chist.html)

Yet to this day, many still don't use any sort of static analysis tool.

~~~
Roboprog
To be honest, I seldom used lint, either, when I was starting out (although I
suppose I cheated by using the Borland IDE in the early 90s). However, when
using gcc in the mid to late 90s, it was just too easy to tack on -Wall
(enable all warnings) to the options. No real excuse not to always check
things, at that point.

------
emmelaich
Something to consider when judging C++ on the basis a Scott Meyer article is
that he tends to find the dark corners.

He is an excellent writer and an excellent language lawyer but he has

> not written production software in over 20 years, and I have never written
> production software in C++. Nope, not ever.

[https://news.ycombinator.com/item?id=9425083](https://news.ycombinator.com/item?id=9425083)

------
chuymax
The webpage navigation was less than optimal on a smartphone. Everytime I
wanted to scroll left or right the page kept changing.

The article was very informative though. Thanks for sharing!

------
wfunction
Can someone explain how this "universal" syntax is supposed to be better than
the old syntax?

~~~
gpderetta
T() had different meaninga depending on T and the context. It could be value
initialisation, a cast, a function declaration(!). Also, when used with
arguments, you couldn't use it to uniformly initialize aggregates and non
aggregates, which is important in generic code.

The T{} syntax can be either a constructor call or aggregate initialization
and never a cast or function definition.

------
couchand
It's really hard to read this article on my phone because the code sample
overflows to the right and left swipes are aggressively interpreted as a
navigation gesture.

