Topic: One variable init form to rule them all, via
Author: "Mark A. Gibbs" <indi.in.the.wired@gmail.com>
Date: Wed, 9 Sep 2015 16:27:17 -0700 (PDT)
Raw View
------=_Part_2682_478987926.1441841237711
Content-Type: multipart/alternative;
boundary="----=_Part_2683_1186173140.1441841237716"
------=_Part_2683_1186173140.1441841237716
Content-Type: text/plain; charset=UTF-8
Scott Meyers's recent post on initialization has brought up a long-time pet
peeve of mine: defining new objects. My beef is not that there are multiple
ways to do it, it's that there is no single way that Just Works(tm)
everywhere, and does the right thing, with robust syntax. The "Almost
Always auto" style proposed by Herb Sutter comes close, but there are some
gotchas with it. It seems to me there is a very simple way to remove those
gotchas, but I've never seen it proposed.
I'm going to start by explaining why I've chosen AAA as the basis for this
proposal. If you're already down with AAA, you can skip to the tl;dr at the
bottom.
Meyers enumerates 4 different ways to declare and initialize a new
variable. With "type" being either a type name or "auto", and "val" being a
lvalue of type "type", they are:
type v = val; // #1
type v(val); // #2
type v = {val}; // #3
type v{val}; // #4
Let's just write #2 off immediately, because of the most vexing arse -
pardon the typo.
#4 is deeply problematic, because the behaviour has changed between C++14
and C++17. So let's drop that, too.
#3 has different behaviour whether "type" is an actually a type name or "
auto". So let's put that aside for the moment.
That leaves us with:
type v = val;
Which, using int, can be either:
int v = 0; // (a)
auto v = 0; // (b)
(a) is fine, but somewhat redundant and occasionally dangerous - if the
type isn't the same on the left and right, you may end up with a conversion
that may be expensive, or may lose information.
So that brings us down to (b), and the whole train of logic above turns to
be a reiteration of the "Almost Always auto" (AAA) argument. For those who
aren't familiar, the AAA argument is that variables should always be
defined using the pattern:
auto v = /* initial value */;
The benefits of this include:
- No unexpected conversions.
- Impossible to have an uninitialized variable.
- Consistent with other modern constructs, easy to read, hard to
misunderstand.
Generally speaking, if you already have a value and you just want to
initialize a copy or move it, you can just use:
auto v = val;
But if you don't have a value, or if you do but you want to be explicit
about the type, you can use:
auto v = type{val}; // or any other constructor arguments, including none
In cases where you *REALLY* want that type, and you don't care if you're
narrowing - or when you *really* want to use a specific constructor, and
the arguments are not just a initializer list of values - then you can use:
auto v = type(val); // Most vexing parse not a problem
The C++ standard allows compilers to elide the copy construction and move
assignment (really a move construction) to a single construction... *even
though it may produce different observable behaviour*. It is (AFAIK) the
only optimization the standard allows that can do that. That means that:
auto v = val; // a single copy construction
auto v = type{val}; // can be a single copy construction
auto v = type(val); // can be a single copy construction
And all modern compilers worth mentioning do the elision.
This also means that:
auto v = type{}; // can be just default construction
So it seems we have a winner for the one, true variable definition format.
But not so fast....
As Meyers noted, this pattern has one case where it doesn't work: types
that are non-copyable and non-movable.
The reasoning that even though the standard *allows* the move (or copy)
construction to be elided, it doesn't *require* it. And compilers have to
pretend they're still going to do it, even though they're not. That is why
this won't compile:
auto v = std::atomic<int>{};
But this restriction is silly and pedantic. There is no way the line above
can reasonably be interpreted as anything else but "I want v to be a
default constructed std::atomic<int>".
And if anyone wants to try to argue that someone might actually want to do
a default construction then move construction when writing that, I call
shenanigans. Because that's not what they're going to get - in any compiler
of note - and the standard blesses this.
Put yourself in the shoes of a C++ newbie who's just learning the language.
Wanting to explore constructors and destructors, ze writes this simple
class:
struct foo
{
foo() { std::cout << "constructing foo\n"; }
~foo() { std::cout << "destructing foo\n"; }
foo(foo const&) = delete;
foo& operator=(foo const&) = delete;
foo(foo&&) = delete;
foo& operator=(foo&&) = delete;
};
int main()
{
foo f;
}
// Output:
// constructing foo
// destructing foo
So far, no problems. But then ze decides to try using the AAA pattern to
define "f":
int main()
{
auto f = foo{};
}
This fails to compile, and the compiler explains that it's because "foo" is
non-movable and non-copyable. "Ah!" says our newbie, thinking ze's learned
something useful. "Well this makes perfect sense! I suppose I'm doing a
construction on the right, and then an assignment to the variable on the
left. Well played C++. Well, now let me experiment to see which special
member function gets used to do the transfer from the right side to the
left."
So now ze writes this:
struct foo
{
foo() { std::cout << "constructing foo\n"; }
~foo() { std::cout << "destructing foo\n"; }
foo(foo const&) { std::cout << "copy constructing foo\n"; }
foo& operator=(foo const&) { std::cout << "copy assigning foo\n"; return *
this; }
foo(foo&&) { std::cout << "move constructing foo\n"; }
foo& operator=(foo&&) { std::cout << "move assigning foo\n"; return *this;
}
};
int main()
{
auto f = foo{};
}
And how is our diligent newbie rewarded for zes experimentation? With this:
// Output:
// constructing foo
// destructing foo
"What... what the flagnar? None of the special functions are used? How can
this be? The compiler said I needed to add them! Why would the compiler
insist on having them if it never uses them! Is this a compiler bug? No?
This absurdity is standard behaviour? To hell with C++. Bring me a Ruby
book."
The cause of all this confusion is the requirement that statements of the
form "type v = type{/*params*/};" or "auto v = type{/*params*/};" (or with
parentheses rather than braces in both cases) *MUST* be interpreted as a
construction on the right, then *another* (move/copy) construction to the
variable on the left (and then a destruction of the temporary)... even
though at the same time compilers are free to elide it all down to a single
construction.
What if, instead, statements of the form "type v = type{/*params*/};" or "auto
v = type{/*params*/};" were interpreted as a single construction, of the
variable "v" which has type "type"?
This would only apply to any statement of the form "XXX varname =
YYY{/*arguments*/};" or "XXX varname = YYY(/*arguments*/);", provided that "
XXX" and "YYY" deduce to the same type (which is obviously true if "XXX" is
"auto"). It would not apply to, for example "float v = int{42};". It *would*
apply to "using number = int; number v = int{42};". It would be exactly
equivalent to "YYY varname{/*arguments*/};" or "YYY varname(/*arguments*/);"
(except, in the latter case, it will not be subject to the most vexing
parse when that applies).
For backwards compatibility, when "type" is movable or copyable, compilers
still have the leeway to implement it as a construction then a move
construction. I don't know of any compilers that actually do that, but,
just in case. That means that the meaning of any code that compiles today
will not change. The only thing that will change is the code that currently
doesn't compile today - when "type" is non-movable and non-copyable - will
now compile (and obviously will only be interpreted as a single
construction, because it can't possibly be interpreted as a construction
then move/copy). I can't imagine this adds any complexity to compilers, and
in fact *removes* a completely unnecessary check that they do today (the
check for move/copy constructability).
The result is we would get a way to define initialized variables that works
consistently in every case, is fairly robust against mistakes and typos,
and has obvious and logical semantics:
int i = 0; // an int
int i = int{0}; // identical to first line (does narrowing check)
int i = int(0); // identical to first line (no narrowing check)
auto i = 0; // identical to first line
auto i = int{0}; // identical to first line (does narrowing check)
auto i = int(0); // identical to first line (no narrowing check)
int i = int{}; // default construction
auto i = int{}; // identical to above
// Same semantics with types with UDLs
std::string s{"foo"}; // std::string
auto s = std::string{"foo"}; // identical to first line
auto s = "foo"s; // using a UDL, (effectively) identical
std::string s = std::string{}; // default construction
auto s = std::string{}; // identical to above
// Non-copyable, non-movable types, too
std::atomic<int> i = 0; // an std::atomic<int>
std::atomic<int> i = std::atomic<int>{0}; // identical to first line
std::atomic<int> i = std::atomic<int>(0); // identical to first line
auto i = std::atomic<int>{0}; // identical to first line
auto i = std::atomic<int>(0); // identical to first line
std::atomic<int> i = std::atomic<int>{}; // default construction
auto i = std::atomic<int>{}; // identical to above
auto a = std::atomic<int>{42};
std::atomic<int> b = a; // won't compile (non-copyable)
auto b = a; // same
std::atomic<int> b = std::move(a); // won't compile (non-movable)
auto b = std::move(a); // same
auto func() -> std::atomic<int>;
std::atomic<int> b = func(); // won't compile (non-movable)
auto b = func(); // same
std::atomic<int> b = std::atomic<int>{func()}; // Won't compile, because
the
// construction on the right
// is invalid. Would work if
// func() return an int.
auto b = std::atomic<int>{func()}; // same
// Familiar behaviours (that already assume elision) are unchanged
std::vector<int> v = std::vector<int>{}; // default construction
auto v = std::vector<int>{}; // same
std::vector<int> v = std::vector<int>{2, 3}; // list construction { 2, 3 }
auto v = std::vector<int>{2, 3}; // same
std::vector<int> v = std::vector<int>(2, 3); // constructs vector { 3, 3 }
auto v = std::vector<int>(2, 3); // same
// If you stick with the policy to always use auto on the left,
// even the initializer list issue that gnaws on Meyers becomes clear:
auto i = 0; // i is int (what else would it be?)
auto i = {0}; // i is initializer_list<int> (what else would it be?)
auto i = int{0}; // i is int (what else would it be?)
// It only gets weird if you do:
int i = 0; // Clear
int i = {0}; // What? You want to assign an initializer_list<int> to an
int?
// Well, I guess it works if there's only one int in the
list...
int i = int{0}; // Clear, but redundant
// Plus all the headaches mentioned in N4014
// But that's a style issue.
So here's the tl;dr bullet point version:
- The AAA style is awesome.
- It has only one gotcha - it fails for non-copyable, non-movable types.
- The language already allows the move/copy to be elided for
copyable/moveable types, and all compilers do that. So the move/copy
requirement is unnecessary. Let's ditch it.
- Let all statements of the form "XXX v = YYY{/*args*/};" where "XXX"
resolves to the same type as "YYY" (which includes when "XXX" is "auto",
obviously), be exactly equivalent to "YYY v{/*args*/};".
- Let all statements of the form "XXX v = YYY(/*args*/);" where "XXX"
resolves to the same type as "YYY" (which includes when "XXX" is "auto",
obviously), be exactly equivalent to "YYY v(/*args*/);"... ignoring the
most vexing parse.
- For the sake of backward compatibility, give compilers the freedom -
when the type is copyable and/or movable - to interpret "XXX v =
YYY{/*args*/};" or "XXX v = YYY(/*args*/);" as a construction followed
by a move/copy construction. (None do, and none likely will, but just in
case. This behaviour could be deprecated, I suppose.)
- In other words, the currently standard-blessed optimization of eliding
the unnecessary temporary construction and move would become not an
optimization, but "the way it's done". Not eliding would become a
"tolerated pessimization".
- Won't change the meaning of any old code. Will make code that
currently won't compile - for silly, pedantic reasons - functional.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_2683_1186173140.1441841237716
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Scott Meyers's recent post on initialization has broug=
ht up a long-time pet peeve of mine: defining new objects. My beef is not t=
hat there are multiple ways to do it, it's that there is no single way =
that Just Works(tm) everywhere, and does the right thing, with robust synta=
x. The "Almost Always auto" style proposed by Herb Sutter comes c=
lose, but there are some gotchas with it. It seems to me there is a very si=
mple way to remove those gotchas, but I've never seen it proposed.<br><=
br>I'm going to start by explaining why I've chosen AAA as the basi=
s for this proposal. If you're already down with AAA, you can skip to t=
he tl;dr at the bottom.<br><br>Meyers enumerates 4 different ways to declar=
e and initialize a new variable. With "<span style=3D"font-family: cou=
rier new,monospace;">type</span>" being either a type name or "<s=
pan style=3D"font-family: courier new,monospace;">auto</span>", and &q=
uot;<span style=3D"font-family: courier new,monospace;">val</span>" be=
ing a lvalue of type "<span style=3D"font-family: courier new,monospac=
e;">type</span>", they are:<br><div class=3D"prettyprint" style=3D"bac=
kground-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border=
-style: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"pr=
ettyprint"><div class=3D"subprettyprint"><span style=3D"color: #000;" class=
=3D"styled-by-prettify">type v </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> val</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
=C2=A0 =C2=A0</span><span style=3D"color: #800;" class=3D"styled-by-prettif=
y">// #1</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r>type v</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify">val</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0 </span><spa=
n style=3D"color: #800;" class=3D"styled-by-prettify">// #2</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br>type v </span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">val</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">};</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> =C2=A0</span><span style=3D"color: #800;" class=3D"styled-by-pre=
ttify">// #3</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br>type v</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify">val</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">};</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0 </span>=
<span style=3D"color: #800;" class=3D"styled-by-prettify">// #4</span></div=
></code></div><br>Let's just write #2 off immediately, because of the m=
ost vexing arse - pardon the typo.<br><br>#4 is deeply problematic, because=
the behaviour has changed between C++14 and C++17. So let's drop that,=
too.<br><br>#3 has different behaviour whether "<span style=3D"font-f=
amily: courier new,monospace;">type</span>" is an actually a type name=
or "<span style=3D"font-family: courier new,monospace;">auto</span>&q=
uot;. So let's put that aside for the moment.<br><br>That leaves us wit=
h:<br><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 2=
50); border-color: rgb(187, 187, 187); border-style: solid; border-width: 1=
px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subpr=
ettyprint"><span style=3D"color: #000;" class=3D"styled-by-prettify">type v=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> val</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">;</span></div></code><=
/div><br>Which, using <span style=3D"font-family: courier new,monospace;">i=
nt</span>, can be either:<br><div class=3D"prettyprint" style=3D"background=
-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style:=
solid; border-width: 1px; word-wrap: break-word;"><code class=3D"prettypri=
nt"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">int</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> v </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan><span style=3D"color: #066;" class=3D"styled-by-prettify">0</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> =C2=A0 </span><span style=3D"c=
olor: #800;" class=3D"styled-by-prettify">// (a)</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> v </span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #066;" class=3D"styled-by-prettif=
y">0</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0</span><=
span style=3D"color: #800;" class=3D"styled-by-prettify">// (b)</span></div=
></code></div><br>(a) is fine, but somewhat redundant and occasionally dang=
erous - if the type isn't the same on the left and right, you may end u=
p with a conversion that may be expensive, or may lose information.<br><br>=
So that brings us down to (b), and the whole train of logic above turns to =
be a reiteration of the "Almost Always auto" (AAA) argument. For =
those who aren't familiar, the AAA argument is that variables should al=
ways be defined using the pattern:<br><div class=3D"prettyprint" style=3D"b=
ackground-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); bord=
er-style: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"=
prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> v </span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify">/* =
initial value */</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">;</span></div></code></div><br>The benefits of this include:<br><ul><=
li>No unexpected conversions.</li><li>Impossible to have an uninitialized v=
ariable.</li><li>Consistent with other modern constructs, easy to read, har=
d to misunderstand.</li></ul><br>Generally speaking, if you already have a =
value and you just want to initialize a copy or move it, you can just use:<=
br><span style=3D"font-family: courier new,monospace;">auto v =3D val;</spa=
n><br><br>But if you don't have a value, or if you do but you want to b=
e explicit about the type, you can use:<br><div class=3D"prettyprint" style=
=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187);=
border-style: solid; border-width: 1px; word-wrap: break-word;"><code clas=
s=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;=
" class=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> v </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> type</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify">val=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">};</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0</span><spa=
n style=3D"color: #800;" class=3D"styled-by-prettify">// or any other const=
ructor arguments, including none</span></div></code></div><br>In cases wher=
e you <b>REALLY</b> want that type, and you don't care if you're na=
rrowing - or when you <i>really</i> want to use a specific constructor, and=
the arguments are not just a initializer list of values - then you can use=
:<br><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 25=
0); border-color: rgb(187, 187, 187); border-style: solid; border-width: 1p=
x; word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subpre=
ttyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> v </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> type</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">val</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> =C2=A0</span><span style=3D"color: #800;" class=3D"styl=
ed-by-prettify">// Most vexing parse not a problem</span></div></code></div=
><br>The C++ standard allows compilers to elide the copy construction and m=
ove assignment (really a move construction) to a single construction... <i>=
even though it may produce different observable behaviour</i>. It is (AFAIK=
) the only optimization the standard allows that can do that. That means th=
at:<br><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, =
250); border-color: rgb(187, 187, 187); border-style: solid; border-width: =
1px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subp=
rettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">auto<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> v </span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> val</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span=
style=3D"color: #800;" class=3D"styled-by-prettify">// a single copy const=
ruction</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
></span><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> v </span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> type</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">val</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">};</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> =C2=A0</span><span style=3D"color: #800;" class=3D"style=
d-by-prettify">// can be a single copy construction</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> v </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> type</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y">val</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0</spa=
n><span style=3D"color: #800;" class=3D"styled-by-prettify">// can be a sin=
gle copy construction</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br></span></div></code></div><br>And all modern compilers worth=
mentioning do the elision.<br><br>This also means that:<br><div class=3D"p=
rettyprint" style=3D"background-color: rgb(250, 250, 250); border-color: rg=
b(187, 187, 187); border-style: solid; border-width: 1px; word-wrap: break-=
word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> v </span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> type</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">{};</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> =C2=A0</span><span style=3D"color: #800;" class=3D"styled=
-by-prettify">// can be just default construction</span></div></code></div>=
<br>So it seems we have a winner for the one, true variable definition form=
at.<br><br>But not so fast....<br><br>As Meyers noted, this pattern has one=
case where it doesn't work: types that are non-copyable and non-movabl=
e.<br><br>The reasoning that even though the standard <i>allows</i> the mov=
e (or copy) construction to be elided, it doesn't <i>require</i> it. An=
d compilers have to pretend they're still going to do it, even though t=
hey're not. That is why this won't compile:<br><div class=3D"pretty=
print" style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187=
, 187, 187); border-style: solid; border-width: 1px; word-wrap: break-word;=
"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"=
color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"color:=
#000;" class=3D"styled-by-prettify"> v </span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">atomic</span><span style=3D"color: #080;" class=3D"styled-by-pret=
tify"><int></span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">{};</span></div></code></div><br>But this restriction is silly and p=
edantic. There is no way the line above can reasonably be interpreted as an=
ything else but "I want <span style=3D"font-family: courier new,monosp=
ace;">v</span> to be a default constructed <span style=3D"font-family: cour=
ier new,monospace;">std::atomic<int></span>".<br><br>And if anyo=
ne wants to try to argue that someone might actually want to do a default c=
onstruction then move construction when writing that, I call shenanigans. B=
ecause that's not what they're going to get - in any compiler of no=
te - and the standard blesses this.<br><br>Put yourself in the shoes of a C=
++ newbie who's just learning the language. Wanting to explore construc=
tors and destructors, ze writes this simple class:<br><br><div class=3D"pre=
ttyprint" style=3D"background-color: rgb(250, 250, 250); border-color: rgb(=
187, 187, 187); border-style: solid; border-width: 1px; word-wrap: break-wo=
rd;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=
=3D"color: #008;" class=3D"styled-by-prettify">struct</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> foo<br></span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"><br>=C2=A0 foo</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">()</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> std</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">cout=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify"><<<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #080;" class=3D"styled-by-prettify">"constructing f=
oo\n"</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">}</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">~</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify">foo</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">()</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> std</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">cout </=
span><span style=3D"color: #660;" class=3D"styled-by-prettify"><<</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: #080;" class=3D"styled-by-prettify">"destructing foo\n=
"</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 <br>=C2=A0 foo</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">foo </span><span style=3D=
"color: #008;" class=3D"styled-by-prettify">const</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">&)</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-=
prettify">delete</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
>=C2=A0 foo</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>&</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">operator</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D(</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">foo </span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">const</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">&)</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">delete</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br>=C2=A0 <br>=C2=A0 foo</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">foo</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>&&)</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: #008;" class=3D"styled-by-prettify">delete</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br>=C2=A0 foo</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">&</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" =
class=3D"styled-by-prettify">operator</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">=3D(</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify">foo</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">&&)</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">delete</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br><br></span><span style=3D"color:=
#008;" class=3D"styled-by-prettify">int</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"> main</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">()</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br>=C2=A0 foo f</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><=
span style=3D"color: #800;" class=3D"styled-by-prettify">// Output:</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span s=
tyle=3D"color: #800;" class=3D"styled-by-prettify">// constructing foo</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><spa=
n style=3D"color: #800;" class=3D"styled-by-prettify">// destructing foo</s=
pan></div></code></div><br>So far, no problems. But then ze decides to try =
using the AAA pattern to define "<span style=3D"font-family: courier n=
ew,monospace;">f</span>":<br><br><div class=3D"prettyprint" style=3D"b=
ackground-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); bord=
er-style: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"=
prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">int</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> main</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">()</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=
=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> f </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> foo</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">{};</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">}</span></div></code></div><br>This fails to =
compile, and the compiler explains that it's because "<span style=
=3D"font-family: courier new,monospace;">foo</span>" is non-movable an=
d non-copyable. "Ah!" says our newbie, thinking ze's learned =
something useful. "Well this makes perfect sense! I suppose I'm do=
ing a construction on the right, and then an assignment to the variable on =
the left. Well played C++. Well, now let me experiment to see which special=
member function gets used to do the transfer from the right side to the le=
ft."<br><br>So now ze writes this:<br><br><div class=3D"prettyprint" s=
tyle=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 1=
87); border-style: solid; border-width: 1px; word-wrap: break-word;"><code =
class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #=
008;" class=3D"styled-by-prettify">struct</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> foo<br></span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br>=C2=A0 foo</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">()</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> s=
td</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify">cout </span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify"><<</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #080;" class=3D"styled-by-prettify">"constructing foo\n"</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">~</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify">foo</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">()</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> s=
td</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify">cout </span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify"><<</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #080;" class=3D"styled-by-prettify">"destructing foo\n"</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"><br>=C2=A0 <br>=C2=A0 foo</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify">foo </span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">const</span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">&)</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> std</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">cout <=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify"><<</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
style=3D"color: #080;" class=3D"styled-by-prettify">"copy constructin=
g foo\n"</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">}</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 foo</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">&</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">operator</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">=3D(</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">foo </span><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">const</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&)</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify">cout </span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify"><<</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #080;" class=3D"styled-by-prettify">"copy assigning foo\n&q=
uot;</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">return</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">*</span><span style=3D"color: #008;" =
class=3D"styled-by-prettify">this</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
>=C2=A0 <br>=C2=A0 foo</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y">foo</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&=
;&)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> std</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify">cout </span><span style=3D"color: #=
660;" class=3D"styled-by-prettify"><<</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #080;" class=
=3D"styled-by-prettify">"move constructing foo\n"</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>=C2=A0 foo</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">&</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">operator</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">=3D(</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">foo</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
&&)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> std</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify">cout </span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify"><<</span><span style=3D"color:=
#000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #080;" c=
lass=3D"styled-by-prettify">"move assigning foo\n"</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">return</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">*</span><span style=3D"color: #008;" class=3D"styled-by-=
prettify">this</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">}</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br><br></span><span style=3D"color:=
#008;" class=3D"styled-by-prettify">int</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"> main</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">()</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br>=C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> f =
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> foo</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">{};</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">}</span></div></code></div><br>And=
how is our diligent newbie rewarded for zes experimentation? With this:<br=
><br><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 25=
0); border-color: rgb(187, 187, 187); border-style: solid; border-width: 1p=
x; word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subpre=
ttyprint"><span style=3D"color: #800;" class=3D"styled-by-prettify">// Outp=
ut:</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></s=
pan><span style=3D"color: #800;" class=3D"styled-by-prettify">// constructi=
ng foo</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
</span><span style=3D"color: #800;" class=3D"styled-by-prettify">// destruc=
ting foo</span></div></code></div><br>"What... what the flagnar? None =
of the special functions are used? How can this be? The compiler said I nee=
ded to add them! Why would the compiler insist on having them if it never u=
ses them! Is this a compiler bug? No? This absurdity is standard behaviour?=
To hell with C++. Bring me a Ruby book."<br><br>The cause of all this=
confusion is the requirement that statements of the form "<span style=
=3D"font-family: courier new,monospace;">type v =3D type{/*params*/};</span=
>" or "<span style=3D"font-family: courier new,monospace;">auto v=
=3D type{/*params*/};</span>" (or with parentheses rather than braces=
in both cases) <b>MUST</b> be interpreted as a construction on the right, =
then <i>another</i> (move/copy) construction to the variable on the left (a=
nd then a destruction of the temporary)... even though at the same time com=
pilers are free to elide it all down to a single construction.<br><br>What =
if, instead, statements of the form "<span style=3D"font-family: couri=
er new,monospace;">type v =3D type{/*params*/};</span>" or "<span=
style=3D"font-family: courier new,monospace;">auto v =3D type{/*params*/};=
</span>" were interpreted as a single construction, of the variable &q=
uot;<span style=3D"font-family: courier new,monospace;">v</span>" whic=
h has type "<span style=3D"font-family: courier new,monospace;">type</=
span>"?<br><br>This would only apply to any statement of the form &quo=
t;<span style=3D"font-family: courier new,monospace;">XXX varname =3D YYY{/=
*arguments*/};</span>" or "<span style=3D"font-family: courier ne=
w,monospace;">XXX varname =3D YYY(/*arguments*/);</span>", provided th=
at "<span style=3D"font-family: courier new,monospace;">XXX</span>&quo=
t; and "<span style=3D"font-family: courier new,monospace;">YYY</span>=
" deduce to the same type (which is obviously true if "<span styl=
e=3D"font-family: courier new,monospace;">XXX</span>" is "<span s=
tyle=3D"font-family: courier new,monospace;">auto</span>"). It would n=
ot apply to, for example "<span style=3D"font-family: courier new,mono=
space;">float v =3D int{42};</span>". It <i>would</i> apply to "<=
span style=3D"font-family: courier new,monospace;">using number =3D int; nu=
mber v =3D int{42};</span>". It would be exactly equivalent to "<=
span style=3D"font-family: courier new,monospace;">YYY varname{/*arguments*=
/};</span>" or "<span style=3D"font-family: courier new,monospace=
;">YYY varname(/*arguments*/);</span>" (except, in the latter case, it=
will not be subject to the most vexing parse when that applies).<br><br>Fo=
r backwards compatibility, when "<span style=3D"font-family: courier n=
ew,monospace;">type</span>" is movable or copyable, compilers still ha=
ve the leeway to implement it as a construction then a move construction. I=
don't know of any compilers that actually do that, but, just in case. =
That means that the meaning of any code that compiles today will not change=
.. The only thing that will change is the code that currently doesn't co=
mpile today - when "<span style=3D"font-family: courier new,monospace;=
">type</span>" is non-movable and non-copyable - will now compile (and=
obviously will only be interpreted as a single construction, because it ca=
n't possibly be interpreted as a construction then move/copy). I can=
9;t imagine this adds any complexity to compilers, and in fact <i>removes</=
i> a completely unnecessary check that they do today (the check for move/co=
py constructability).<br><br>The result is we would get a way to define ini=
tialized variables that works consistently in every case, is fairly robust =
against mistakes and typos, and has obvious and logical semantics:<br><br><=
div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); bo=
rder-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; wor=
d-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subprettypri=
nt"><span style=3D"color: #008;" class=3D"styled-by-prettify">int</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> i </span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #066=
;" class=3D"styled-by-prettify">0</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color: #80=
0;" class=3D"styled-by-prettify">// an int</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">int</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> i </span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">int<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><sp=
an style=3D"color: #066;" class=3D"styled-by-prettify">0</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> =C2=A0 </span><span style=3D"color:=
#800;" class=3D"styled-by-prettify">// identical to first line (does narro=
wing check)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">int</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> i </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">int</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">(</span><span style=3D"color: #066;" class=
=3D"styled-by-prettify">0</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> =C2=A0 </span><span style=3D"color: #800;" class=3D"styled-by-prett=
ify">// identical to first line (no narrowing check)</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: =
#008;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"> i </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #066;" class=3D"styled-by-pr=
ettify">0</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =
=C2=A0 =C2=A0 </span><span style=3D"color: #800;" class=3D"styled-by-pretti=
fy">// identical to first line</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"styled=
-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> i </span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">int</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D=
"color: #066;" class=3D"styled-by-prettify">0</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">};</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> =C2=A0</span><span style=3D"color: #800;" class=
=3D"styled-by-prettify">// identical to first line (does narrowing check)</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><=
span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> i </span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color:=
#000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">int</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">(</span><span style=3D"color: #066;" class=3D"styled-b=
y-prettify">0</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=
=A0</span><span style=3D"color: #800;" class=3D"styled-by-prettify">// iden=
tical to first line (no narrowing check)</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"><br><br></span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">int</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> i </span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">in=
t</span><span style=3D"color: #660;" class=3D"styled-by-prettify">{};</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 </span><=
span style=3D"color: #800;" class=3D"styled-by-prettify">// default constru=
ction</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><=
/span><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> i </span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">int</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">{};</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> =C2=A0</span><span style=3D"color: #800;" class=3D"st=
yled-by-prettify">// identical to above</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"><br><br></span><span style=3D"color: #800;" cl=
ass=3D"styled-by-prettify">// Same semantics with types with UDLs</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br>std</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D=
"color: #008;" class=3D"styled-by-prettify">string</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> s</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">{</span><span style=3D"color: #080;" class=
=3D"styled-by-prettify">"foo"</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">};</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"col=
or: #800;" class=3D"styled-by-prettify">// std::string</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> s </span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> std</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">::</span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">string</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
{</span><span style=3D"color: #080;" class=3D"styled-by-prettify">"foo=
"</span><span style=3D"color: #660;" class=3D"styled-by-prettify">};</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0</spa=
n><span style=3D"color: #800;" class=3D"styled-by-prettify">// identical to=
first line</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">auto<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> s </span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #080;" class=3D"styled-by-prettify">"foo"</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">s</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0</span><span style=3D"color: #800;" class=3D"styled-by-prettify">// usin=
g a UDL, (effectively) identical</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br><br>std</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">::</span><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">string</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> s </span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">string</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">{};</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0</span><span style=
=3D"color: #800;" class=3D"styled-by-prettify">// default construction</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> s </span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">::</span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">string</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">{};</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #800;" c=
lass=3D"styled-by-prettify">// identical to above</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br><br></span><span style=3D"color:=
#800;" class=3D"styled-by-prettify">// Non-copyable, non-movable types, to=
o</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>std</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">atomic</span><span s=
tyle=3D"color: #080;" class=3D"styled-by-prettify"><int></span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> i </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #066;=
" class=3D"styled-by-prettify">0</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 </span><span style=3D"color: #800;" class=3D"styled-by-prettify"=
>// an std::atomic<int></span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br>std</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">atomic</span><span style=3D"color: #080;" class=3D"styled-by-pretti=
fy"><int></span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> i </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> std</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">atomic</span><span st=
yle=3D"color: #080;" class=3D"styled-by-prettify"><int></span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"c=
olor: #066;" class=3D"styled-by-prettify">0</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">};</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> =C2=A0 </span><span style=3D"color: #800;" class=
=3D"styled-by-prettify">// identical to first line</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br>std</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify">atomic</span><span style=3D"color: #080;" clas=
s=3D"styled-by-prettify"><int></span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> i </span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> std</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">at=
omic</span><span style=3D"color: #080;" class=3D"styled-by-prettify"><in=
t></span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span style=3D"color: #066;" class=3D"styled-by-prettify">0</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> =C2=A0 </span><span style=3D"c=
olor: #800;" class=3D"styled-by-prettify">// identical to first line</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span =
style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> i </span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">atomic</span><span style=3D"color: #080;" class=3D"style=
d-by-prettify"><int></span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">{</span><span style=3D"color: #066;" class=3D"styled-by-pre=
ttify">0</span><span style=3D"color: #660;" class=3D"styled-by-prettify">};=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #800=
;" class=3D"styled-by-prettify">// identical to first line</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> i </span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">atomic</span><span style=3D"color: #080;" class=3D"styled-by-pret=
tify"><int></span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">(</span><span style=3D"color: #066;" class=3D"styled-by-prettify">0<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #800;" class=
=3D"styled-by-prettify">// identical to first line</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br><br>std</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">atomic</span><span style=3D"color: #080;" =
class=3D"styled-by-prettify"><int></span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"> i </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> std</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y">atomic</span><span style=3D"color: #080;" class=3D"styled-by-prettify">&=
lt;int></span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
{};</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0=
</span><span style=3D"color: #800;" class=3D"styled-by-prettify">// defaul=
t construction</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">au=
to</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> i </spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"> std</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">atomic</span><span style=3D"color: #=
080;" class=3D"styled-by-prettify"><int></span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">{};</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 </span><span style=3D"color: #800;" class=3D"styled-by-prettify">// ide=
ntical to above</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br><br></span><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> a =
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> std</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify">atomic</span><span style=3D"col=
or: #080;" class=3D"styled-by-prettify"><int></span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #066=
;" class=3D"styled-by-prettify">42</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">};</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br>std</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify">atomic</span><span style=3D"color: #080;" class=3D"styled-by-prettify"=
><int></span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> b </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> a</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #800;" class=3D"styled-by-prettify">// won't compile (non-copyable)</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><=
span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> b </span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color:=
#000;" class=3D"styled-by-prettify"> a</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span=
style=3D"color: #800;" class=3D"styled-by-prettify">// same</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"><br>std</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">atomic</span><span style=3D"color: #=
080;" class=3D"styled-by-prettify"><int></span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> b </span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">move</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">a</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0</span><span st=
yle=3D"color: #800;" class=3D"styled-by-prettify">// won't compile (non=
-movable)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> b </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> std</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">move</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">a</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"co=
lor: #800;" class=3D"styled-by-prettify">// same</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br><br></span><span style=3D"color: =
#008;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"> func</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">()</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">-></span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify">atomic</spa=
n><span style=3D"color: #080;" class=3D"styled-by-prettify"><int></sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br>std</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify">atomic</span><span style=3D"color:=
#080;" class=3D"styled-by-prettify"><int></span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> b </span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> func</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">();</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> =C2=A0</span><span style=3D"color: #800;" class=3D"styled-by-p=
rettify">// won't compile (non-movable)</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> b </span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> func</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">();</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color: #=
800;" class=3D"styled-by-prettify">// same</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"><br>std</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify">atomic</span><span style=3D"color: #080;" class=3D"sty=
led-by-prettify"><int></span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> b </span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify">atomic</sp=
an><span style=3D"color: #080;" class=3D"styled-by-prettify"><int></s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify">func</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">()};</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> =C2=A0</span><span style=3D"color=
: #800;" class=3D"styled-by-prettify">// Won't compile, because the</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 </span><span style=3D"color: #800;" class=3D"styled-by-prettify"=
>// construction on the right</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #800=
;" class=3D"styled-by-prettify">// is invalid. Would work if</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 <=
/span><span style=3D"color: #800;" class=3D"styled-by-prettify">// func() r=
eturn an int.</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">aut=
o</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> b </span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> std</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">atomic</span><span style=3D"color: #=
080;" class=3D"styled-by-prettify"><int></span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify">func</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">()};</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><spa=
n style=3D"color: #800;" class=3D"styled-by-prettify">// same</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><span sty=
le=3D"color: #800;" class=3D"styled-by-prettify">// Familiar behaviours (th=
at already assume elision) are unchanged</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"><br>std</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">vector</span><span style=3D"color: #080;" class=3D"style=
d-by-prettify"><int></span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> v </span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify">vector</span=
><span style=3D"color: #080;" class=3D"styled-by-prettify"><int></spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">{};</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0</span><span st=
yle=3D"color: #800;" class=3D"styled-by-prettify">// default construction</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><=
span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> v </span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color:=
#000;" class=3D"styled-by-prettify"> std</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">vector</span><span style=3D"color: #080;" class=3D"=
styled-by-prettify"><int></span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">{};</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span=
style=3D"color: #800;" class=3D"styled-by-prettify">// same</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"><br><br>std</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify">vector</span><span style=3D"colo=
r: #080;" class=3D"styled-by-prettify"><int></span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> v </span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify">vector</span><span style=3D"color: #080;" class=3D"styled-by-pr=
ettify"><int></span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">{</span><span style=3D"color: #066;" class=3D"styled-by-prettify">=
2</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=3D"color: #066;" class=3D"styled-by-prettify">3</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">};</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> =C2=A0</span><span style=3D"color: #800;" c=
lass=3D"styled-by-prettify">// list construction { 2, 3 }</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> v </span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> std</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">vector</span><span style=3D"color: #080;" class=3D"styled-by-prettif=
y"><int></span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">{</span><span style=3D"color: #066;" class=3D"styled-by-prettify">2</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #066;" class=3D"styled-by-prettify">3</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">};</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
</span><span style=3D"color: #800;" class=3D"styled-by-prettify">// same</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br>std</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">vector</span><span s=
tyle=3D"color: #080;" class=3D"styled-by-prettify"><int></span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> v </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> std</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">vector</span><span style=3D"color: #080;" class=
=3D"styled-by-prettify"><int></span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">(</span><span style=3D"color: #066;" class=3D"styl=
ed-by-prettify">2</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: #066;" class=3D"styled-by-prettify">3</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0</span><span style=3D=
"color: #800;" class=3D"styled-by-prettify">// constructs vector { 3, 3 }</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><=
span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> v </span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color:=
#000;" class=3D"styled-by-prettify"> std</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">vector</span><span style=3D"color: #080;" class=3D"=
styled-by-prettify"><int></span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">(</span><span style=3D"color: #066;" class=3D"styled-b=
y-prettify">2</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #066;" class=3D"styled-by-prettify">3</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0</span><span style=3D"color: #800;" class=3D"styled-by-pre=
ttify">// same</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"><br><br></span><span style=3D"color: #800;" class=3D"styled-by-prettify=
">// If you stick with the policy to always use auto on the left,</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span sty=
le=3D"color: #800;" class=3D"styled-by-prettify">// even the initializer li=
st issue that gnaws on Meyers becomes clear:</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> i </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><span style=3D"color: #066;" class=3D"styled-by-prettify"=
>0</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0 =
=C2=A0 </span><span style=3D"color: #800;" class=3D"styled-by-prettify">// =
i is int (what else would it be?)</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> i </span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><sp=
an style=3D"color: #066;" class=3D"styled-by-prettify">0</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0 </span><span style=3D=
"color: #800;" class=3D"styled-by-prettify">// i is initializer_list<int=
> (what else would it be?)</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-=
by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> i </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">int</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"=
color: #066;" class=3D"styled-by-prettify">0</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">};</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> =C2=A0</span><span style=3D"color: #800;" class=
=3D"styled-by-prettify">// i is int (what else would it be?)</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><span styl=
e=3D"color: #800;" class=3D"styled-by-prettify">// It only gets weird if yo=
u do:</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><=
/span><span style=3D"color: #008;" class=3D"styled-by-prettify">int</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> i </span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #0=
66;" class=3D"styled-by-prettify">0</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #800;" c=
lass=3D"styled-by-prettify">// Clear</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">int</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> i </span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><s=
pan style=3D"color: #066;" class=3D"styled-by-prettify">0</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0 </span><span style=3D=
"color: #800;" class=3D"styled-by-prettify">// What? You want to assign an =
initializer_list<int> to an int?</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0</span><span style=3D"color: #800;" class=3D"styled-by-=
prettify">// Well, I guess it works if there's only one int in the list=
....</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">int</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> i </span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">int</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">{</span><span style=3D"color: #066;" class=3D"styl=
ed-by-prettify">0</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">};</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
=C2=A0</span><span style=3D"color: #800;" class=3D"styled-by-prettify">// C=
lear, but redundant</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br></span><span style=3D"color: #800;" class=3D"styled-by-prettif=
y">// Plus all the headaches mentioned in N4014</span><span style=3D"color:=
#000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #800;=
" class=3D"styled-by-prettify">// But that's a style issue.</span></div=
></code></div><br>So here's the tl;dr bullet point version:<br><ul><li>=
The AAA style is awesome.</li><li>It has only one gotcha - it fails for non=
-copyable, non-movable types.</li><li>The language already allows the move/=
copy to be elided for copyable/moveable types, and all compilers do that. S=
o the move/copy requirement is unnecessary. Let's ditch it.</li><li>Let=
all statements of the form "<span style=3D"font-family: courier new,m=
onospace;">XXX v =3D YYY{/*args*/};</span>" where "<span style=3D=
"font-family: courier new,monospace;">XXX</span>" resolves to the same=
type as "<span style=3D"font-family: courier new,monospace;">YYY</spa=
n>" (which includes when "<span style=3D"font-family: courier new=
,monospace;">XXX</span>" is "<span style=3D"font-family: courier =
new,monospace;">auto</span>", obviously), be exactly equivalent to &qu=
ot;<span style=3D"font-family: courier new,monospace;">YYY v{/*args*/};</sp=
an>".</li><li>Let all statements of the form "<span style=3D"font=
-family: courier new,monospace;">XXX v =3D YYY(/*args*/);</span>" wher=
e "<span style=3D"font-family: courier new,monospace;">XXX</span>"=
; resolves to the same type as "<span style=3D"font-family: courier ne=
w,monospace;">YYY</span>" (which includes when "<span style=3D"fo=
nt-family: courier new,monospace;">XXX</span>" is "<span style=3D=
"font-family: courier new,monospace;">auto</span>", obviously), be exa=
ctly equivalent to "<span style=3D"font-family: courier new,monospace;=
">YYY v(/*args*/);</span>"... ignoring the most vexing parse.</li><li>=
For the sake of backward compatibility, give compilers the freedom - when t=
he type is copyable and/or movable - to interpret "<span style=3D"font=
-family: courier new,monospace;">XXX v =3D YYY{/*args*/};</span>" or &=
quot;<span style=3D"font-family: courier new,monospace;">XXX v =3D YYY(/*ar=
gs*/);</span>" as a construction followed by a move/copy construction.=
(None do, and none likely will, but just in case. This behaviour could be =
deprecated, I suppose.)</li><li>In other words, the currently standard-bles=
sed optimization of eliding the unnecessary temporary construction and move=
would become not an optimization, but "the way it's done". N=
ot eliding would become a "tolerated pessimization".</li><li>Won&=
#39;t change the meaning of any old code. Will make code that currently won=
't compile - for silly, pedantic reasons - functional.<br></li></ul></d=
iv>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_2683_1186173140.1441841237716--
------=_Part_2682_478987926.1441841237711--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Thu, 10 Sep 2015 02:34:15 +0300
Raw View
On 10 September 2015 at 02:27, Mark A. Gibbs
<indi.in.the.wired@gmail.com> wrote:
> But not so fast....
> As Meyers noted, this pattern has one case where it doesn't work: types that
> are non-copyable and non-movable.
> The reasoning that even though the standard allows the move (or copy)
> construction to be elided, it doesn't require it. And compilers have to
> pretend they're still going to do it, even though they're not. That is why
> this won't compile:
> auto v = std::atomic<int>{};
> But this restriction is silly and pedantic. There is no way the line above
> can reasonably be interpreted as anything else but "I want v to be a default
> constructed std::atomic<int>".
The EWG disagreed:
http://cplusplus.github.io/EWG/ewg-closed.html#124
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: "Mark A. Gibbs" <indi.in.the.wired@gmail.com>
Date: Wed, 9 Sep 2015 16:48:49 -0700 (PDT)
Raw View
------=_Part_1768_1063735635.1441842530037
Content-Type: multipart/alternative;
boundary="----=_Part_1769_1102700207.1441842530037"
------=_Part_1769_1102700207.1441842530037
Content-Type: text/plain; charset=UTF-8
On Wednesday, 9 September 2015 19:34:17 UTC-4, Ville Voutilainen wrote:
>
> On 10 September 2015 at 02:27, Mark A. Gibbs
> <indi.in....@gmail.com <javascript:>> wrote:
> > But not so fast....
> > As Meyers noted, this pattern has one case where it doesn't work: types
> that
> > are non-copyable and non-movable.
> > The reasoning that even though the standard allows the move (or copy)
> > construction to be elided, it doesn't require it. And compilers have to
> > pretend they're still going to do it, even though they're not. That is
> why
> > this won't compile:
> > auto v = std::atomic<int>{};
> > But this restriction is silly and pedantic. There is no way the line
> above
> > can reasonably be interpreted as anything else but "I want v to be a
> default
> > constructed std::atomic<int>".
>
> The EWG disagreed:
> http://cplusplus.github.io/EWG/ewg-closed.html#124
That doesn't seem to be the same point.
// I am talking about, for example. either of
tuple<int> t = tuple<int>{0};
auto t = tuple<int>{0};
// I am not talking about:
tuple<int> t = {0};
// Which is what N4014 was about
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_1769_1102700207.1441842530037
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Wednesday, 9 September 2015 19:34:17 UTC-4, Ville Voutilainen wrote:<bl=
ockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border=
-left: 1px #ccc solid;padding-left: 1ex;">On 10 September 2015 at 02:27, Ma=
rk A. Gibbs
<br><<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"=
yRK5cf4uAgAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:&=
#39;;return true;" onclick=3D"this.href=3D'javascript:';return true=
;">indi.in....@gmail.com</a>> wrote:
<br>> But not so fast....
<br>> As Meyers noted, this pattern has one case where it doesn't wo=
rk: types that
<br>> are non-copyable and non-movable.
<br>> The reasoning that even though the standard allows the move (or co=
py)
<br>> construction to be elided, it doesn't require it. And compiler=
s have to
<br>> pretend they're still going to do it, even though they're =
not. That is why
<br>> this won't compile:
<br>> auto v =3D std::atomic<int>{};
<br>> But this restriction is silly and pedantic. There is no way the li=
ne above
<br>> can reasonably be interpreted as anything else but "I want v =
to be a default
<br>> constructed std::atomic<int>".
<br>
<br>The EWG disagreed:
<br><a href=3D"http://cplusplus.github.io/EWG/ewg-closed.html#124" target=
=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D'http://www.goo=
gle.com/url?q\75http%3A%2F%2Fcplusplus.github.io%2FEWG%2Fewg-closed.html%23=
124\46sa\75D\46sntz\0751\46usg\75AFQjCNGKUTlrxGHUyKbwFXrOq5FWZC4tbQ';re=
turn true;" onclick=3D"this.href=3D'http://www.google.com/url?q\75http%=
3A%2F%2Fcplusplus.github.io%2FEWG%2Fewg-closed.html%23124\46sa\75D\46sntz\0=
751\46usg\75AFQjCNGKUTlrxGHUyKbwFXrOq5FWZC4tbQ';return true;">http://cp=
lusplus.github.io/<wbr>EWG/ewg-closed.html#124</a></blockquote><div>=C2=A0<=
br>That doesn't seem to be the same point.<br><br><div class=3D"prettyp=
rint" style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187,=
187, 187); border-style: solid; border-width: 1px; word-wrap: break-word;"=
><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"c=
olor: #800;" class=3D"styled-by-prettify">// I am talking about, for exampl=
e. either of</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br>tuple</span><span style=3D"color: #080;" class=3D"styled-by-prettify"=
><int></span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> t </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> tuple</span=
><span style=3D"color: #080;" class=3D"styled-by-prettify"><int></spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span s=
tyle=3D"color: #066;" class=3D"styled-by-prettify">0</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">};</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=A0 t </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> tuple</span><span style=3D"color: #080;" cl=
ass=3D"styled-by-prettify"><int></span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">{</span><span style=3D"color: #066;" class=3D"s=
tyled-by-prettify">0</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">};</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br></span><span style=3D"color: #800;" class=3D"styled-by-prettify">// I=
am not talking about:</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br>tuple</span><span style=3D"color: #080;" class=3D"styled-by=
-prettify"><int></span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> t </span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><sp=
an style=3D"color: #066;" class=3D"styled-by-prettify">0</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #80=
0;" class=3D"styled-by-prettify">// Which is what N4014 was about</span></d=
iv></code></div><br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_1769_1102700207.1441842530037--
------=_Part_1768_1063735635.1441842530037--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Thu, 10 Sep 2015 03:26:33 +0300
Raw View
On 10 September 2015 at 02:48, Mark A. Gibbs
<indi.in.the.wired@gmail.com> wrote:
>> > this won't compile:
>> > auto v = std::atomic<int>{};
>> > But this restriction is silly and pedantic. There is no way the line
>> > above
>> > can reasonably be interpreted as anything else but "I want v to be a
>> > default
>> > constructed std::atomic<int>".
>>
>> The EWG disagreed:
>> http://cplusplus.github.io/EWG/ewg-closed.html#124
>
>
> That doesn't seem to be the same point.
>
> // I am talking about, for example. either of
> tuple<int> t = tuple<int>{0};
> auto t = tuple<int>{0};
> // I am not talking about:
> tuple<int> t = {0};
> // Which is what N4014 was about
The point is that EWG disagreed with the part which you claimed cannot be
reasonably be interpreted as anything else but default-constructing. We didn't
want to remove the semantic check for copy/move even for the case where the
copy/move is elided. That semantic check is what makes your example
be rejected.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: "Mark A. Gibbs" <indi.in.the.wired@gmail.com>
Date: Wed, 9 Sep 2015 18:52:05 -0700 (PDT)
Raw View
------=_Part_5_961064161.1441849925839
Content-Type: multipart/alternative;
boundary="----=_Part_6_630784479.1441849925839"
------=_Part_6_630784479.1441849925839
Content-Type: text/plain; charset=UTF-8
On Wednesday, 9 September 2015 20:26:36 UTC-4, Ville Voutilainen wrote:
>
> The point is that EWG disagreed with the part which you claimed cannot be
> reasonably be interpreted as anything else but default-constructing. We
> didn't
> want to remove the semantic check for copy/move even for the case where
> the
> copy/move is elided. That semantic check is what makes your example
> be rejected.
>
It still doesn't look like the same point to me. The item you pointed to
appears to be about explicit versus non-explicit construction, not
copyability (or movability). I'm not talking about "type t = {};", I'm
talking about "type t = type{};". What I'm proposing has absolutely no
impact on explicitness, nor is it impacted by it. If there is actually an
argument relevant to copy/movability, I'd like to hear it.
I have never seen anyone, anywhere, suggest that using the construct "auto
x = T{};" (or "T x = T{};") is a way to test for copyability (or
movability) in generic code. I have never seen anyone say: "I write 'T
x{...};' in generic code when I only require that constructor signature,
and I write 'auto x = T{...};' to additionally constrain for copy and/or
movability." In fact, I would say anyone who did that was just creating
maintenance headaches. By contrast, I have seen several beginners surprised
and annoyed when it doesn't work for some types, like atomics, mutexes,
locks, and other RAII-implementing types. (Even Meyers highlights this
frustration, as his "Question 2".)
When someone wants to require copy/movability there are plenty of other,
less obtuse, ways to do it:
auto t2 = t1
auto t2 = T{t1};
T t2{t1};
T t2 = t1;
T t2 = T{t1};
// etc., and of course traits, and eventually concepts
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_6_630784479.1441849925839
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Wednesday, 9 September 2015 20:26:36 UTC-4, Ville Vouti=
lainen wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">The point is tha=
t EWG disagreed with the part which you claimed cannot be
<br>reasonably be interpreted as anything else but default-constructing. We=
didn't
<br>want to remove the semantic check for copy/move even for the case where=
the
<br>copy/move is elided. That semantic check is what makes your example
<br>be rejected.
<br></blockquote><div><br>It still doesn't look like the same point to =
me. The item you pointed to appears to be about explicit versus non-explici=
t construction, not copyability (or movability). I'm not talking about =
"<span style=3D"font-family: courier new,monospace;">type t =3D {};</s=
pan>", I'm talking about "<span style=3D"font-family: courier=
new,monospace;">type t =3D type{};</span>". What I'm proposing ha=
s absolutely no impact on explicitness, nor is it impacted by it. If there =
is actually an argument relevant to copy/movability, I'd like to hear i=
t.<br><br>I have never seen anyone, anywhere, suggest that using the constr=
uct "<span style=3D"font-family: courier new,monospace;">auto x =3D T{=
};</span>" (or "<span style=3D"font-family: courier new,monospace=
;">T x =3D T{};</span>") is a way to test for copyability (or movabili=
ty) in generic code. I have never seen anyone say: "I write '<span=
style=3D"font-family: courier new,monospace;">T x{...};</span>' in gen=
eric code when I only require that constructor signature, and I write '=
<span style=3D"font-family: courier new,monospace;">auto x =3D T{...};</spa=
n>' to additionally constrain for copy and/or movability." In fact=
, I would say anyone who did that was just creating maintenance headaches. =
By contrast, I have seen several beginners surprised and annoyed when it do=
esn't work for some types, like atomics, mutexes, locks, and other RAII=
-implementing types. (Even Meyers highlights this frustration, as his "=
;Question 2".)<br><br>When someone wants to require copy/movability th=
ere are plenty of other, less obtuse, ways to do it:<br><div class=3D"prett=
yprint" style=3D"background-color: rgb(250, 250, 250); border-color: rgb(18=
7, 187, 187); border-style: solid; border-width: 1px; word-wrap: break-word=
;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D=
"color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> t2 </span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> t1<br></span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> t2 </span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> T</span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify">t1</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>T t2</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">t1</span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">};</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>T t2 </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> t1</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br>T t2 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> T</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">t1</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">};</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #800;" =
class=3D"styled-by-prettify">// etc., and of course traits, and eventually =
concepts</span></div></code></div><br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_6_630784479.1441849925839--
------=_Part_5_961064161.1441849925839--
.
Author: David Krauss <potswa@gmail.com>
Date: Thu, 10 Sep 2015 10:53:44 +0800
Raw View
--Apple-Mail=_6401DA10-429A-45EC-95F4-80AA1362B3F8
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
Let me start by saying, I hate the looseness of the elision rule too too. I=
f I had more time, I=E2=80=99d be proposing to require elision where it=E2=
=80=99s de-facto standard.
> On 2015=E2=80=9309=E2=80=9310, at 7:27 AM, Mark A. Gibbs <indi.in.the.wir=
ed@gmail.com> wrote:
>=20
> Scott Meyers's recent post
http://scottmeyers.blogspot.com/2015/09/thoughts-on-vagaries-of-c-initializ=
ation.html <http://scottmeyers.blogspot.com/2015/09/thoughts-on-vagaries-of=
-c-initialization.html>
> on initialization has brought up a long-time pet peeve of mine: defining =
new objects. My beef is not that there are multiple ways to do it, it's tha=
t there is no single way that Just Works(tm) everywhere, and does the right=
thing, with robust syntax. The "Almost Always auto" style proposed by Herb=
Sutter comes close, but there are some gotchas with it. It seems to me the=
re is a very simple way to remove those gotchas, but I've never seen it pro=
posed.
Elision hasn=E2=80=99t been mentioned yet :( .
No syntax Just Works=E2=84=A2 because classes really do different things. S=
tatements should not have unbounded meaning.
> I'm going to start by explaining why I've chosen AAA as the basis for thi=
s proposal. If you're already down with AAA, you can skip to the tl;dr at t=
he bottom.
>=20
> Meyers enumerates 4 different ways to declare and initialize a new variab=
le. With "type" being either a type name or "auto", and "val" being a lvalu=
e of type "type", they are:
> type v =3D val; // #1
> type v(val); // #2
> type v =3D {val}; // #3
> type v{val}; // #4
>=20
> Let's just write #2 off immediately, because of the most vexing arse - pa=
rdon the typo.
No, MVP happens only with an empty argument list. Otherwise #2 looks like a=
function call, so it=E2=80=99s appropriate for constructors that behave mo=
re like functions and less like aggregate initialization. As a special case=
, aggregating no values is the same as calling a nullary function. Adding v=
alues/parameters, the concepts diverge.
#2 is sometimes required to disambiguate an initializer list (aggregate-lik=
e) from a parameter list (function-like).
> #4 is deeply problematic, because the behaviour has changed between C++14=
and C++17. So let's drop that, too.
Huh? What change? I think that if the committee agreed with that consequenc=
e, they wouldn=E2=80=99t have changed it.
So now you=E2=80=99re saying that there should always be an equals sign, dr=
opping all direct-initialization. This is drifting far away from the specif=
ic topic of elision.
An equals sign is reminiscent of mathematical values: It joins two mathemat=
ical objects and asserts their equality. I prefer to avoid it for things th=
at don=E2=80=99t have values.
Ah, now Sutter=E2=80=99s article has loaded on my slow connection. C++17 de=
precates treating a braced-init-list as an initializer_list value when ther=
e=E2=80=99s no equals sign. This makes sense, because initializer_list is d=
efinitely forming a new value there (although it doesn=E2=80=99t always beh=
ave with value semantics).
> #3 has different behaviour whether "type" is an actually a type name or "=
auto". So let's put that aside for the moment.
>=20
> That leaves us with:
> type v =3D val;
=E2=80=A6 which, for nontrivial expressions that we encounter most often, s=
uggests that val is a factory function call.
> Which, using int, can be either:
When discussing elision, int, being trivially copyable, is not a good defau=
lt illustrative type.
> int v =3D 0; // (a)
> auto v =3D 0; // (b)
>=20
> (a) is fine, but somewhat redundant and occasionally dangerous - if the t=
ype isn't the same on the left and right, you may end up with a conversion =
that may be expensive, or may lose information.
Hence almost always auto. A lot of more-experienced programmers aren=E2=80=
=99t 100% on that bandwagon.
> So that brings us down to (b), and the whole train of logic above turns t=
o be a reiteration of the "Almost Always auto" (AAA) argument. For those wh=
o aren't familiar, the AAA argument is that variables should always be defi=
ned using the pattern:
> auto v =3D /* initial value */;
>=20
> The benefits of this include:
> No unexpected conversions.
Some sort of conversion is needed to obtain a value from an expression temp=
late object, so this isn=E2=80=99t axiomatic.
> Impossible to have an uninitialized variable.
> Consistent with other modern constructs, easy to read, hard to misunderst=
and.
If you extend the meaning of #1 to include #2, #3, and #4, won=E2=80=99t th=
at increase the potential for misunderstanding?
Syntax has no inherent value by itself; it just stands for semantic concept=
s. If you think that #1 ain=E2=80=99t broke, why fix it? (Still no mention =
of elision in this post.)
> Generally speaking, if you already have a value and you just want to init=
ialize a copy or move it, you can just use:
> auto v =3D val;
>=20
> But if you don't have a value, or if you do but you want to be explicit a=
bout the type, you can use:
> auto v =3D type{val}; // or any other constructor arguments, including n=
one
Or a factory function, which furthermore needs to worry about the return st=
atement.
(snip)
> But not so fast....
>=20
> As Meyers noted, this pattern has one case where it doesn't work: types t=
hat are non-copyable and non-movable.
Such types tend to lack value semantics. Not a coincidence that the equals =
sign becomes undefined.
> The reasoning that even though the standard allows the move (or copy) con=
struction to be elided, it doesn't require it. And compilers have to preten=
d they're still going to do it, even though they're not. That is why this w=
on't compile:
> auto v =3D std::atomic<int>{};
>=20
> But this restriction is silly and pedantic. There is no way the line abov=
e can reasonably be interpreted as anything else but "I want v to be a defa=
ult constructed std::atomic<int>=E2=80=9D.
No, atomic variables have special synchronization requirements. They=E2=80=
=99re a refinement of volatile. I look at that statement and I see two dist=
inct variables joined by an equals sign. Take away the object-ness of std::=
atomic and it becomes conceptually vague.
> And if anyone wants to try to argue that someone might actually want to d=
o a default construction then move construction when writing that, I call s=
henanigans. Because that's not what they're going to get - in any compiler =
of note - and the standard blesses this.
They don=E2=80=99t want that, and they won=E2=80=99t get it, because it=E2=
=80=99s nonsense. This argument is a logical fallacy of false supposition. =
The language is correct to prevent having two objects in that statement. Ye=
t it would be incorrect to allow the statement to work with one object, bec=
ause std::atomic is a type where one object emphatically never represents t=
wo values.
> Put yourself in the shoes of a C++ newbie who's just learning the languag=
e. Wanting to explore constructors and destructors, ze writes this simple c=
lass:
Writing random code from no semantic premises, and guessing at meaning from=
the perspective of a naive person, is not part of language design.
The solution to this problem is that newbies shouldn=E2=80=99t write non-va=
lue-semantic classes. Deleting the move constructor is a red flag, indicati=
ng that programming assistance is needed.
(Snip =E2=80=94 the newbie did not seek help. This seldom ends well in any =
language.)
Here=E2=80=99s my take:
The problem with copy-initialization is that it=E2=80=99s sometimes used wi=
th no equals sign, such as in passing, returning, and throwing. The languag=
e treats it as a conservative choice when it=E2=80=99s impossible to guaran=
tee that two values are the same object. However, this guarantee can always=
be made when passing, throwing, or returning a prvalue. The language/ABI i=
nterface is interfering with the programmer=E2=80=99s stated intentions.
But the elision problem isn=E2=80=99t limited to copy-initialization at all=
.. Consider:
struct s {
explicit s() =3D default;
s( s && ) =3D delete;
};
s f() { return s{}; } // No equals sign nor conversion, but still copy-init=
ialization. Excessive language conservatism.
s q{ f() }; // Direct-initalization can also be ill-formed due to lack of m=
ove constructor.
I posit that the above snippet should work. It goes far enough out of its w=
ay to avoid suggesting value semantics, and all implementations can guarant=
ee that the move constructor isn=E2=80=99t needed.
Unfortunately, I don=E2=80=99t have time right now for deeper discussion, m=
uch less to write a proposal.
And BTW, I agree with Ville=E2=80=99s that your proposal is closely aligned=
with N4014. They both result from blaming the problems of non-value-semant=
ic classes on the equals sign instead of the class. The equals sign is a sa=
fety mechanism to protect you from thorny types; getting rid of its signifi=
cance will only open the gates to more nastiness.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--Apple-Mail=_6401DA10-429A-45EC-95F4-80AA1362B3F8
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><div class=3D"">Le=
t me start by saying, I hate the looseness of the elision rule too too. If =
I had more time, I=E2=80=99d be proposing to require elision where it=E2=80=
=99s de-facto standard.</div><div class=3D""><br class=3D""></div><br class=
=3D""><div><blockquote type=3D"cite" class=3D""><div class=3D"">On 2015=E2=
=80=9309=E2=80=9310, at 7:27 AM, Mark A. Gibbs <<a href=3D"mailto:indi.i=
n.the.wired@gmail.com" class=3D"">indi.in.the.wired@gmail.com</a>> wrote=
:</div><br class=3D"Apple-interchange-newline"><div class=3D""><div dir=3D"=
ltr" class=3D"">Scott Meyers's recent post </div></div></blockquote><div><b=
r class=3D""></div><div><a href=3D"http://scottmeyers.blogspot.com/2015/09/=
thoughts-on-vagaries-of-c-initialization.html" class=3D"">http://scottmeyer=
s.blogspot.com/2015/09/thoughts-on-vagaries-of-c-initialization.html</a></d=
iv><br class=3D""><blockquote type=3D"cite" class=3D""><div class=3D""><div=
dir=3D"ltr" class=3D"">on initialization has brought up a long-time pet pe=
eve of mine: defining new objects. My beef is not that there are multiple w=
ays to do it, it's that there is no single way that Just Works(tm) everywhe=
re, and does the right thing, with robust syntax. The "Almost Always auto" =
style proposed by Herb Sutter comes close, but there are some gotchas with =
it. It seems to me there is a very simple way to remove those gotchas, but =
I've never seen it proposed.<br class=3D""></div></div></blockquote><div><b=
r class=3D""></div><div>Elision hasn=E2=80=99t been mentioned yet :( .</div=
><div><br class=3D""></div><div>No syntax Just Works=E2=84=A2 because class=
es really do different things. Statements should not have unbounded meaning=
..</div><br class=3D""><blockquote type=3D"cite" class=3D""><div class=3D"">=
<div dir=3D"ltr" class=3D"">I'm going to start by explaining why I've chose=
n AAA as the basis for this proposal. If you're already down with AAA, you =
can skip to the tl;dr at the bottom.<br class=3D""><br class=3D"">Meyers en=
umerates 4 different ways to declare and initialize a new variable. With "<=
span style=3D"font-family: courier new,monospace;" class=3D"">type</span>" =
being either a type name or "<span style=3D"font-family: courier new,monosp=
ace;" class=3D"">auto</span>", and "<span style=3D"font-family: courier new=
,monospace;" class=3D"">val</span>" being a lvalue of type "<span style=3D"=
font-family: courier new,monospace;" class=3D"">type</span>", they are:<br =
class=3D""><div class=3D"prettyprint" style=3D"background-color: rgb(250, 2=
50, 250); border-color: rgb(187, 187, 187); border-style: solid; border-wid=
th: 1px; word-wrap: break-word;"><code class=3D"prettyprint">type v <span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">=3D</span> val<span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">;</span> <span=
style=3D"color: #800;" class=3D"styled-by-prettify">// #1</span><br class=
=3D"">type v<span style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an>val<span style=3D"color: #660;" class=3D"styled-by-prettify">);</span> &=
nbsp; <span style=3D"color: #800;" class=3D"styled-by-prettify">// #=
2</span><br class=3D"">type v <span style=3D"color: #660;" class=3D"styled-=
by-prettify">=3D</span> <span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">{</span>val<span style=3D"color: #660;" class=3D"styled-by-prettify"=
>};</span> <span style=3D"color: #800;" class=3D"styled-by-prettify">=
// #3</span><br class=3D"">type v<span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">{</span>val<span style=3D"color: #660;" class=3D"styled-by-=
prettify">};</span> <span style=3D"color: #800;" class=3D"sty=
led-by-prettify">// #4</span></code></div><br class=3D"">Let's just write #=
2 off immediately, because of the most vexing arse - pardon the typo.<br cl=
ass=3D""></div></div></blockquote><div><br class=3D""></div><div>No, MVP ha=
ppens only with an empty argument list. Otherwise #2 looks like a function =
call, so it=E2=80=99s appropriate for constructors that behave more like fu=
nctions and less like aggregate initialization. As a special case, aggregat=
ing no values is the same as calling a nullary function. Adding values/para=
meters, the concepts diverge.</div><div><br class=3D""></div><div>#2 is som=
etimes required to disambiguate an initializer list (aggregate-like) from a=
parameter list (function-like).</div><br class=3D""><blockquote type=3D"ci=
te" class=3D""><div class=3D""><div dir=3D"ltr" class=3D"">#4 is deeply pro=
blematic, because the behaviour has changed between C++14 and C++17. So let=
's drop that, too.<br class=3D""></div></div></blockquote><div><br class=3D=
""></div><div>Huh? What change? I think that if the committee agreed with t=
hat consequence, they wouldn=E2=80=99t have changed it.</div><div><br class=
=3D""></div><div>So now you=E2=80=99re saying that there should always be a=
n equals sign, dropping all direct-initialization. This is drifting far awa=
y from the specific topic of elision.</div><div><br class=3D""></div><div>A=
n equals sign is reminiscent of mathematical values: It joins two mathemati=
cal objects and asserts their equality. I prefer to avoid it for things tha=
t don=E2=80=99t have values.</div><div><br class=3D""></div><div>Ah, now Su=
tter=E2=80=99s article has loaded on my slow connection. C++17 deprecates t=
reating a <i class=3D"">braced-init-list</i> as an <font face=3D"Courier" c=
lass=3D"">initializer_list</font> value when there=E2=80=99s no equals sign=
.. This makes sense, because <span style=3D"font-family: Courier;" clas=
s=3D"">initializer_list</span> is definitely forming a new value there=
(although it doesn=E2=80=99t always behave with value semantics).</div><di=
v><br class=3D""></div><blockquote type=3D"cite" class=3D""><div class=3D""=
><div dir=3D"ltr" class=3D"">#3 has different behaviour whether "<span styl=
e=3D"font-family: courier new,monospace;" class=3D"">type</span>" is an act=
ually a type name or "<span style=3D"font-family: courier new,monospace;" c=
lass=3D"">auto</span>". So let's put that aside for the moment.<br class=3D=
""><br class=3D"">That leaves us with:<br class=3D""><div class=3D"prettypr=
int" style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, =
187, 187); border-style: solid; border-width: 1px; word-wrap: break-word;">=
<code class=3D"prettyprint">type v <span style=3D"color: #660;" class=3D"st=
yled-by-prettify">=3D</span> val<span style=3D"color: #660;" class=3D"style=
d-by-prettify">;</span></code></div></div></div></blockquote><div><br class=
=3D""></div><div>=E2=80=A6 which, for nontrivial expressions that we encoun=
ter most often, suggests that <font face=3D"Courier" class=3D"">val</font> =
is a factory function call.</div><div><br class=3D""></div><blockquote type=
=3D"cite" class=3D""><div class=3D""><div dir=3D"ltr" class=3D"">Which, usi=
ng <span style=3D"font-family: courier new,monospace;" class=3D"">int</span=
>, can be either:<br class=3D""></div></div></blockquote><div><br class=3D"=
"></div><div>When discussing elision, <font face=3D"Courier" class=3D"">int=
</font>, being trivially copyable, is not a good default illustrative type.=
</div><br class=3D""><blockquote type=3D"cite" class=3D""><div class=3D""><=
div dir=3D"ltr" class=3D""><div class=3D"prettyprint" style=3D"background-c=
olor: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: s=
olid; border-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint=
"><span style=3D"color: #008;" class=3D"styled-by-prettify">int</span> v <s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span> <span st=
yle=3D"color: #066;" class=3D"styled-by-prettify">0</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">;</span> <span style=3D"col=
or: #800;" class=3D"styled-by-prettify">// (a)</span><br class=3D""><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">auto</span> v <span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">=3D</span> <span style=3D"c=
olor: #066;" class=3D"styled-by-prettify">0</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">;</span> <span style=3D"color: #800;=
" class=3D"styled-by-prettify">// (b)</span></code></div><br class=3D"">(a)=
is fine, but somewhat redundant and occasionally dangerous - if the type i=
sn't the same on the left and right, you may end up with a conversion that =
may be expensive, or may lose information.<br class=3D""></div></div></bloc=
kquote><div><br class=3D""></div><div>Hence <i class=3D"">almost</i> a=
lways <font face=3D"Courier" class=3D"">auto</font>. A lot of more-experien=
ced programmers aren=E2=80=99t 100% on that bandwagon.</div><br class=3D"">=
<blockquote type=3D"cite" class=3D""><div class=3D""><div dir=3D"ltr" class=
=3D"">So that brings us down to (b), and the whole train of logic above tur=
ns to be a reiteration of the "Almost Always auto" (AAA) argument. For thos=
e who aren't familiar, the AAA argument is that variables should always be =
defined using the pattern:<br class=3D""><div class=3D"prettyprint" style=
=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187);=
border-style: solid; border-width: 1px; word-wrap: break-word;"><code clas=
s=3D"prettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>auto</span> v <span style=3D"color: #660;" class=3D"styled-by-prettify">=
=3D</span> <span style=3D"color: #800;" class=3D"styled-by-prettify">/* ini=
tial value */</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">;</span></code></div><br class=3D"">The benefits of this include:<br cla=
ss=3D""><ul class=3D""><li class=3D"">No unexpected conversions.</li></ul><=
/div></div></blockquote><div>Some sort of conversion is needed to obtain a =
value from an expression template object, so this isn=E2=80=99t axiomatic.<=
/div><blockquote type=3D"cite" class=3D""><div class=3D""><div dir=3D"ltr" =
class=3D""><ul class=3D""><li class=3D"">Impossible to have an uninitialize=
d variable.</li><li class=3D"">Consistent with other modern constructs, eas=
y to read, hard to misunderstand.</li></ul></div></div></blockquote><div>If=
you extend the meaning of #1 to include #2, #3, and #4, won=E2=80=99t that=
increase the potential for misunderstanding?</div><div><br class=3D""></di=
v><div>Syntax has no inherent value by itself; it just stands for semantic =
concepts. If you think that #1 ain=E2=80=99t broke, why fix it? (Still no m=
ention of elision in this post.)</div><br class=3D""><blockquote type=3D"ci=
te" class=3D""><div class=3D""><div dir=3D"ltr" class=3D"">Generally speaki=
ng, if you already have a value and you just want to initialize a copy or m=
ove it, you can just use:<br class=3D""><span style=3D"font-family: courier=
new,monospace;" class=3D"">auto v =3D val;</span><br class=3D""><br class=
=3D"">But if you don't have a value, or if you do but you want to be explic=
it about the type, you can use:<br class=3D""><div class=3D"prettyprint" st=
yle=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 18=
7); border-style: solid; border-width: 1px; word-wrap: break-word;"><code c=
lass=3D"prettyprint"><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">auto</span> v <span style=3D"color: #660;" class=3D"styled-by-prettify"=
>=3D</span> type<span style=3D"color: #660;" class=3D"styled-by-prettify">{=
</span>val<span style=3D"color: #660;" class=3D"styled-by-prettify">};</spa=
n> <span style=3D"color: #800;" class=3D"styled-by-prettify">// or an=
y other constructor arguments, including none</span></code></div></div></di=
v></blockquote><div><br class=3D""></div><div>Or a factory function, which =
furthermore needs to worry about the <font face=3D"Courier" class=3D"">retu=
rn</font> statement.</div><div><br class=3D""></div>(snip)</div><div><br cl=
ass=3D""><blockquote type=3D"cite" class=3D""><div class=3D""><div dir=3D"l=
tr" class=3D"">But not so fast....<br class=3D""><br class=3D"">As Meyers n=
oted, this pattern has one case where it doesn't work: types that are non-c=
opyable and non-movable.<br class=3D""></div></div></blockquote><div><br cl=
ass=3D""></div><div>Such types tend to lack value semantics. Not a coincide=
nce that the equals sign becomes undefined.</div><br class=3D""><blockquote=
type=3D"cite" class=3D""><div class=3D""><div dir=3D"ltr" class=3D"">The r=
easoning that even though the standard <i class=3D"">allows</i> the move (o=
r copy) construction to be elided, it doesn't <i class=3D"">require</i> it.=
And compilers have to pretend they're still going to do it, even though th=
ey're not. That is why this won't compile:<br class=3D""><div class=3D"pret=
typrint" style=3D"background-color: rgb(250, 250, 250); border-color: rgb(1=
87, 187, 187); border-style: solid; border-width: 1px; word-wrap: break-wor=
d;"><code class=3D"prettyprint"><span style=3D"color: #008;" class=3D"style=
d-by-prettify">auto</span> v <span style=3D"color: #660;" class=3D"styled-b=
y-prettify">=3D</span> std<span style=3D"color: #660;" class=3D"styled-by-p=
rettify">::</span>atomic<span style=3D"color: #080;" class=3D"styled-by-pre=
ttify"><int></span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">{};</span></code></div><br class=3D"">But this restriction is silly=
and pedantic. There is no way the line above can reasonably be interpreted=
as anything else but "I want <span style=3D"font-family: courier new,monos=
pace;" class=3D"">v</span> to be a default constructed <span style=3D"font-=
family: courier new,monospace;" class=3D"">std::atomic<int></span>=E2=
=80=9D.<br class=3D""></div></div></blockquote><div><br class=3D""></div><d=
iv>No, <font face=3D"Courier" class=3D"">atomic</font> variables have speci=
al synchronization requirements. They=E2=80=99re a refinement of <font face=
=3D"Courier" class=3D"">volatile</font>. I look at that statement and I see=
two distinct variables joined by an equals sign. Take away the object-ness=
of <font face=3D"Courier" class=3D"">std::atomic</font> and it becomes con=
ceptually vague.</div><br class=3D""><blockquote type=3D"cite" class=3D""><=
div class=3D""><div dir=3D"ltr" class=3D"">And if anyone wants to try to ar=
gue that someone might actually want to do a default construction then move=
construction when writing that, I call shenanigans. Because that's not wha=
t they're going to get - in any compiler of note - and the standard blesses=
this.<br class=3D""></div></div></blockquote><div><br class=3D""></div><di=
v>They don=E2=80=99t want that, and they won=E2=80=99t get it, because it=
=E2=80=99s nonsense. This argument is a logical fallacy of false suppositio=
n. The language is correct to prevent having two objects in that statement.=
Yet it would be incorrect to allow the statement to work with one object, =
because <font face=3D"Courier" class=3D"">std::atomic</font> is a type wher=
e one object emphatically <i class=3D"">never</i> represents two =
values.</div><br class=3D""><blockquote type=3D"cite" class=3D""><div class=
=3D""><div dir=3D"ltr" class=3D"">Put yourself in the shoes of a C++ newbie=
who's just learning the language. Wanting to explore constructors and dest=
ructors, ze writes this simple class:<br class=3D""></div></div></blockquot=
e><div><br class=3D""></div><div>Writing random code from no semantic premi=
ses, and guessing at meaning from the perspective of a naive person, is not=
part of language design.</div><div><br class=3D""></div><div>The solution =
to this problem is that newbies shouldn=E2=80=99t write non-value-semantic =
classes. Deleting the move constructor is a red flag, indicating that progr=
amming assistance is needed.</div><div><br class=3D""></div><div>(Snip =E2=
=80=94 the newbie did not seek help. This seldom ends well in any language.=
)</div></div><div class=3D""><br class=3D""></div><div class=3D""><br class=
=3D""></div>Here=E2=80=99s my take:<div class=3D""><br class=3D""><div clas=
s=3D"">The problem with copy-initialization is that it=E2=80=99s sometimes =
used with no equals sign, such as in passing, returning, and throwing. The =
language treats it as a conservative choice when it=E2=80=99s impossible to=
guarantee that two values are the same object. However, this guarantee <i =
class=3D"">can</i> always be made when passing, throwing, or returning=
a prvalue. The language/ABI interface is interfering with the programmer=
=E2=80=99s stated intentions.</div></div><div class=3D""><br class=3D""></d=
iv><div class=3D"">But the elision problem isn=E2=80=99t limited to copy-in=
itialization at all. Consider:</div><div class=3D""><br class=3D""></div><d=
iv class=3D""><font face=3D"Courier" class=3D"">struct s {</font></div><div=
class=3D""><font face=3D"Courier" class=3D""> explicit s() =
=3D default;</font></div><div class=3D""><font face=3D"Courier" class=3D"">=
s( s && ) =3D delete;</font></div><div class=3D""><fo=
nt face=3D"Courier" class=3D"">};</font></div><div class=3D""><font face=3D=
"Courier" class=3D""><br class=3D""></font></div><div class=3D""><font face=
=3D"Courier" class=3D"">s f() { return s{}; } // No equals sign nor convers=
ion, but still copy-initialization. Excessive language conservatism.</font>=
</div><div class=3D""><font face=3D"Courier" class=3D""><br class=3D""></fo=
nt></div><div class=3D""><font face=3D"Courier" class=3D"">s q{ f() }; // D=
irect-initalization can also be ill-formed due to lack of move constructor.=
</font></div><div class=3D""><br class=3D""></div><div class=3D"">I posit t=
hat the above snippet should work. It goes far enough out of its way to avo=
id suggesting value semantics, and all implementations can guarantee that t=
he move constructor isn=E2=80=99t needed.</div><div class=3D""><br class=3D=
""></div><div class=3D"">Unfortunately, I don=E2=80=99t have time right now=
for deeper discussion, much less to write a proposal.</div><div class=3D""=
><br class=3D""></div><div class=3D"">And BTW, I agree with Ville=E2=80=99s=
that your proposal is closely aligned with N4014. They both result from bl=
aming the problems of non-value-semantic classes on the equals sign instead=
of the class. The equals sign is a safety mechanism to protect you from th=
orny types; getting rid of its significance will only open the gates to mor=
e nastiness.</div><div class=3D""><br class=3D""></div></body></html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--Apple-Mail=_6401DA10-429A-45EC-95F4-80AA1362B3F8--
.
Author: David Krauss <potswa@gmail.com>
Date: Thu, 10 Sep 2015 10:59:01 +0800
Raw View
--Apple-Mail=_81366538-3B1E-4131-A493-53614CF33A3D
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
> On 2015=E2=80=9309=E2=80=9310, at 10:53 AM, David Krauss <potswa@gmail.co=
m> wrote:
>=20
> No, MVP happens only with an empty argument list.
inb4 the pedants, with int q( int() ), there=E2=80=99s still an empty list =
in the inner expression/declarator, and disambiguation is accomplished by c=
hanging it, specifically, to braces: int q( int{} ).
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--Apple-Mail=_81366538-3B1E-4131-A493-53614CF33A3D
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2015=E2=80=9309=
=E2=80=9310, at 10:53 AM, David Krauss <<a href=3D"mailto:potswa@gmail.c=
om" class=3D"">potswa@gmail.com</a>> wrote:</div><br class=3D"Apple-inte=
rchange-newline"><div class=3D""><span style=3D"font-family: Helvetica; fon=
t-size: 12px; font-style: normal; font-variant: normal; font-weight: normal=
; letter-spacing: normal; line-height: normal; orphans: auto; text-align: s=
tart; text-indent: 0px; text-transform: none; white-space: normal; widows: =
auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; displ=
ay: inline !important;" class=3D"">No, MVP happens only with an empty argum=
ent list.</span></div></blockquote></div><br class=3D""><div class=3D"">inb=
4 the pedants, with <font face=3D"Courier" class=3D"">int q( int() )</font>=
, there=E2=80=99s still an empty list in the inner expression/declarator, a=
nd disambiguation is accomplished by changing it, specifically, to braces:&=
nbsp;<span style=3D"font-family: Courier;" class=3D"">int q( int{} )</span>=
..</div></body></html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--Apple-Mail=_81366538-3B1E-4131-A493-53614CF33A3D--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Thu, 10 Sep 2015 08:14:28 +0300
Raw View
On 10 September 2015 at 05:53, David Krauss <potswa@gmail.com> wrote:
> #4 is deeply problematic, because the behaviour has changed between C++14
> and C++17. So let's drop that, too.
>
>
> Huh? What change? I think that if the committee agreed with that
> consequence, they wouldn=E2=80=99t have changed it.
That's N3922..
> So now you=E2=80=99re saying that there should always be an equals sign, =
dropping
> all direct-initialization. This is drifting far away from the specific to=
pic
> of elision.
> An equals sign is reminiscent of mathematical values: It joins two
> mathematical objects and asserts their equality. I prefer to avoid it for
> things that don=E2=80=99t have values.
> Ah, now Sutter=E2=80=99s article has loaded on my slow connection. C++17 =
deprecates
> treating a braced-init-list as an initializer_list value when there=E2=80=
=99s no
> equals sign. This makes sense, because initializer_list is definitely
> forming a new value there (although it doesn=E2=80=99t always behave with=
value
> semantics).
...but there's no deprecation, and N3922 applies as a Defect Report all the =
way
back to C++11, and gcc implements it in its C++11 mode. MSVC doesn't
have conformance modes, but they also already ship with the N3922
change included.
Then again, even with N3922,
auto x{atomic<int>{}};
still doesn't work because even there, a semantic check for copy/move
is performed.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.
Author: David Krauss <potswa@gmail.com>
Date: Thu, 10 Sep 2015 13:24:49 +0800
Raw View
> On 2015=E2=80=9309=E2=80=9310, at 1:14 PM, Ville Voutilainen <ville.vouti=
lainen@gmail.com> wrote:
>=20
> ..but there's no deprecation, and N3922 applies as a Defect Report all th=
e way
> back to C++11, and gcc implements it in its C++11 mode. MSVC doesn't
> have conformance modes, but they also already ship with the N3922
> change included.
OK, retroactive elimination and wiping-out. Stronger than deprecation.
> Then again, even with N3922,
>=20
> auto x{atomic<int>{}};
>=20
> still doesn't work because even there, a semantic check for copy/move
> is performed.
Right. I don=E2=80=99t favor that stylistically, but I=E2=80=99ll take it i=
f it can=E2=80=99t be surgically separated from non-movable factory functio=
ns which are a hole in the language.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.
Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Thu, 10 Sep 2015 09:34:51 -0700 (PDT)
Raw View
------=_Part_7895_1315063866.1441902891548
Content-Type: multipart/alternative;
boundary="----=_Part_7896_859907327.1441902891555"
------=_Part_7896_859907327.1441902891555
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Thursday, September 10, 2015 at 1:24:56 AM UTC-4, David Krauss wrote:
>
>
> >=20
> > still doesn't work because even there, a semantic check for copy/move=
=20
> > is performed.=20
>
> Right. I don=E2=80=99t favor that stylistically, but I=E2=80=99ll take it=
if it can=E2=80=99t be=20
> surgically separated from non-movable factory functions which are a hole =
in=20
> the language.=20
>
I would love to have factory functions for non-movable types. It seems that=
=20
with return value optimization, most of the work is already=20
done. Unfortunately I think adding support would require new syntax of some=
=20
kind.
=20
Maybe an attribute [[emplace]]. This would force RVO, enabling support for=
=20
"returning" a non-movable object and also allowing the programmer to=20
enforce that RVO is used for functions which return movable types.
=20
[[emplace]] Widget makeWidget() { return Widget(); }
[[emplace]] auto x =3D makeWidget();
[[emplace]] auto x =3D std::atomic<int>{};
=20
Of course with that approach people might just end up sprinkling=20
[[emplace]] in all of their functions to optimize and increase=20
compatibility...
=20
Another option could be a new "inplace" initialization operator to use=20
instead of =3D. I don't have a full specification for such a thing but=20
it might look something like this:
static_assert(is_movable<Widget>::value =3D=3D false);
Widget makeWidget() <=3D; //Declare an inplace return function that must do=
=20
RVO.
auto w <=3D makeWidget(); //inplace construct w
auto i <=3D std::atomic<int>{}; //inplace construct i
=20
Such an operator could even be used for value semantic types to specify the=
=20
specific intent of direct construction vs copying. Op <=3D is a strawman fo=
r=20
bikeshedding, but I think it could work since the comparison <=3D doesn't=
=20
make sense in a new variable declaration or function signature.
=20
In general the C++ language is designed around value semantics (i.e.=20
construct and move) but has pretty poor support for inplace construction of=
=20
immobile types. There are many (I would argue artificial) holes in the=20
language and library when you need to work with immobile types.
=20
=20
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_7896_859907327.1441902891555
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br>On Thursday, September 10, 2015 at 1:24:56 AM UTC-4, D=
avid Krauss wrote:<blockquote style=3D"margin: 0px 0px 0px 0.8ex; padding-l=
eft: 1ex; border-left-color: rgb(204, 204, 204); border-left-width: 1px; bo=
rder-left-style: solid;" class=3D"gmail_quote">
<br>>=20
<br>> still doesn't work because even there, a semantic check for co=
py/move
<br>> is performed.
<br>
<br>Right. I don=E2=80=99t favor that stylistically, but I=E2=80=99ll take =
it if it can=E2=80=99t be surgically separated from non-movable factory fun=
ctions which are a hole in the language.
<br></blockquote><div><br>I=C2=A0would love to have factory functions for n=
on-movable types.=C2=A0It seems that with=C2=A0return value optimization,=
=C2=A0most of the work is already </div><div>done.=C2=A0Unfortunately I thi=
nk adding support would require new syntax of some kind.</div><div>=C2=A0</=
div><div>Maybe an attribute [[emplace]]. This would force RVO, enabling sup=
port for "returning" a non-movable object and also allowing the p=
rogrammer to enforce that RVO is used for functions which return movable ty=
pes.</div><div>=C2=A0</div><div><div style=3D"border: 1px solid rgb(187, 18=
7, 187); word-wrap: break-word; background-color: rgb(250, 250, 250);" clas=
s=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"subprettyprint"=
><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">[[</=
span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify">empl=
ace</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prett=
ify">]]</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prett=
ify"> </span><span style=3D"color: rgb(102, 0, 102);" class=3D"styled-by-pr=
ettify">Widget</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-b=
y-prettify"> makeWidget</span><span style=3D"color: rgb(102, 102, 0);" clas=
s=3D"styled-by-prettify">()</span><span style=3D"color: rgb(0, 0, 0);" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: rgb(102, 102, 0);" c=
lass=3D"styled-by-prettify">{</span><span style=3D"color: rgb(0, 0, 0);" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: rgb(0, 0, 136);" c=
lass=3D"styled-by-prettify">return</span><span style=3D"color: rgb(0, 0, 0)=
;" class=3D"styled-by-prettify"> </span><span style=3D"color: rgb(102, 0, 1=
02);" class=3D"styled-by-prettify">Widget</span><span style=3D"color: rgb(1=
02, 102, 0);" class=3D"styled-by-prettify">();</span><span style=3D"color: =
rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><span style=3D"color: r=
gb(102, 102, 0);" class=3D"styled-by-prettify">}</span><span style=3D"color=
: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br></span><span style=3D"col=
or: rgb(102, 102, 0);" class=3D"styled-by-prettify">[[</span><span style=3D=
"color: rgb(0, 0, 0);" class=3D"styled-by-prettify">emplace</span><span sty=
le=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">]]</span><span=
style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><span =
style=3D"color: rgb(0, 0, 136);" class=3D"styled-by-prettify">auto</span><s=
pan style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> x </span><=
span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">=3D</s=
pan><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> make=
Widget</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-pr=
ettify">();</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-p=
rettify"><br></span><span style=3D"color: rgb(102, 102, 0);" class=3D"style=
d-by-prettify">[[</span><span style=3D"color: rgb(0, 0, 0);" class=3D"style=
d-by-prettify">emplace</span><span style=3D"color: rgb(102, 102, 0);" class=
=3D"styled-by-prettify">]]</span><span style=3D"color: rgb(0, 0, 0);" class=
=3D"styled-by-prettify"> </span><span style=3D"color: rgb(0, 0, 136);" clas=
s=3D"styled-by-prettify">auto</span><span style=3D"color: rgb(0, 0, 0);" cl=
ass=3D"styled-by-prettify"> x </span><span style=3D"color: rgb(102, 102, 0)=
;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: rgb(0, 0, 0=
);" class=3D"styled-by-prettify"> std</span><span style=3D"color: rgb(102, =
102, 0);" class=3D"styled-by-prettify">::</span><span style=3D"color: rgb(0=
, 0, 0);" class=3D"styled-by-prettify">atomic</span><span style=3D"color: r=
gb(0, 136, 0);" class=3D"styled-by-prettify"><int></span><span style=
=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">{};</span><span =
style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br></span></di=
v></code></div></div><div>=C2=A0</div><div>Of course with that approach peo=
ple might just end up sprinkling [[emplace]]=C2=A0in all of their functions=
=C2=A0to optimize and increase compatibility...</div><div>=C2=A0</div><div>=
Another option could be a new "inplace" initialization operator t=
o use instead of =3D. I don't have a=C2=A0full specification for such a=
thing but it=C2=A0might look something like this:</div><code class=3D"pret=
typrint"><div style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: bre=
ak-word; background-color: rgb(250, 250, 250);" class=3D"prettyprint"><div =
class=3D"subprettyprint">static_assert(is_movable<Widget>::value =3D=
=3D false);<br><br>Widget makeWidget() <=3D; //Declare an inplace return=
function that must do RVO.<br>auto w <=3D makeWidget(); //inplace const=
ruct w<br>auto i <=3D std::atomic<int>{}; //inplace construct i</d=
iv></div></code><div style=3D"border: 1px solid rgb(187, 187, 187); word-wr=
ap: break-word; background-color: rgb(250, 250, 250);" class=3D"prettyprint=
"><div class=3D"subprettyprint"></div></div><div>=C2=A0</div><div>Such an o=
perator could even be used for value semantic types to specify the specific=
intent of direct construction vs copying. Op <=3D is a strawman for bik=
eshedding, but I think it could work since the comparison <=3D doesn'=
;t make sense in a new variable declaration or function signature.</div><di=
v>=C2=A0</div><div>In general the C++ language is designed around value sem=
antics (i.e. construct and move) but has pretty poor support for inplace co=
nstruction of immobile types. There are many (I would argue artificial) hol=
es in the language and library when you need to work with immobile types.</=
div><div>=C2=A0</div><div>=C2=A0</div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_7896_859907327.1441902891555--
------=_Part_7895_1315063866.1441902891548--
.
Author: David Krauss <potswa@gmail.com>
Date: Fri, 11 Sep 2015 04:33:54 +0800
Raw View
--Apple-Mail=_EB441ECC-A73D-478C-9CB2-07E68AAA906E
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
> On 2015=E2=80=9309=E2=80=9311, at 12:34 AM, Matthew Fioravante <fmatthew5=
876@gmail.com> wrote:
>=20
> I would love to have factory functions for non-movable types. It seems th=
at with return value optimization, most of the work is already=20
> done. Unfortunately I think adding support would require new syntax of so=
me kind.
I think it would only require guaranteeing elision when initializing from (=
or returning) a prvalue of the same type.
Named return values would be icing on the cake, but that=E2=80=99s more com=
plicated.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--Apple-Mail=_EB441ECC-A73D-478C-9CB2-07E68AAA906E
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2015=E2=80=9309=
=E2=80=9311, at 12:34 AM, Matthew Fioravante <<a href=3D"mailto:fmatthew=
5876@gmail.com" class=3D"">fmatthew5876@gmail.com</a>> wrote:</div><br c=
lass=3D"Apple-interchange-newline"><div class=3D""><div style=3D"font-famil=
y: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; fo=
nt-weight: normal; letter-spacing: normal; line-height: normal; orphans: au=
to; text-align: start; text-indent: 0px; text-transform: none; white-space:=
normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" =
class=3D"">I would love to have factory functions for non-movable type=
s. It seems that with return value optimization, most of the=
work is already<span class=3D"Apple-converted-space"> </span></div><d=
iv style=3D"font-family: Helvetica; font-size: 12px; font-style: normal; fo=
nt-variant: normal; font-weight: normal; letter-spacing: normal; line-heigh=
t: normal; orphans: auto; text-align: start; text-indent: 0px; text-transfo=
rm: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-tex=
t-stroke-width: 0px;" class=3D"">done. Unfortunately I think adding su=
pport would require new syntax of some kind.</div></div></blockquote><div><=
br class=3D""></div><div>I think it would only require guaranteeing elision=
when initializing from (or returning) a prvalue of the same type.</div><di=
v><br class=3D""></div><div>Named return values would be icing on the cake,=
but that=E2=80=99s more complicated.</div><div><br class=3D""></div></div>=
</body></html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--Apple-Mail=_EB441ECC-A73D-478C-9CB2-07E68AAA906E--
.
Author: Richard Smith <richard@metafoo.co.uk>
Date: Thu, 10 Sep 2015 13:37:34 -0700
Raw View
--001a1143dda0a7264a051f6a918b
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Thu, Sep 10, 2015 at 9:34 AM, Matthew Fioravante <fmatthew5876@gmail.com=
>
wrote:
>
> On Thursday, September 10, 2015 at 1:24:56 AM UTC-4, David Krauss wrote:
>>
>>
>> >
>> > still doesn't work because even there, a semantic check for copy/move
>> > is performed.
>>
>> Right. I don=E2=80=99t favor that stylistically, but I=E2=80=99ll take i=
t if it can=E2=80=99t be
>> surgically separated from non-movable factory functions which are a hole=
in
>> the language.
>>
>
> I would love to have factory functions for non-movable types.
>
struct Immovable {
Immovable(int, int);
Immovable(const Immovable&) =3D delete;
void operator=3D(const Immovable&) =3D delete;
};
Immovable factory() {
return {1, 2};
}
auto &&val =3D factory();
It seems that with return value optimization, most of the work is already
> done. Unfortunately I think adding support would require new syntax of
> some kind.
>
> Maybe an attribute [[emplace]]. This would force RVO, enabling support fo=
r
> "returning" a non-movable object and also allowing the programmer to
> enforce that RVO is used for functions which return movable types.
>
> [[emplace]] Widget makeWidget() { return Widget(); }
> [[emplace]] auto x =3D makeWidget();
> [[emplace]] auto x =3D std::atomic<int>{};
>
> Of course with that approach people might just end up sprinkling
> [[emplace]] in all of their functions to optimize and increase
> compatibility...
>
> Another option could be a new "inplace" initialization operator to use
> instead of =3D. I don't have a full specification for such a thing but
> it might look something like this:
> static_assert(is_movable<Widget>::value =3D=3D false);
>
> Widget makeWidget() <=3D; //Declare an inplace return function that must =
do
> RVO.
> auto w <=3D makeWidget(); //inplace construct w
> auto i <=3D std::atomic<int>{}; //inplace construct i
>
> Such an operator could even be used for value semantic types to specify
> the specific intent of direct construction vs copying. Op <=3D is a straw=
man
> for bikeshedding, but I think it could work since the comparison <=3D doe=
sn't
> make sense in a new variable declaration or function signature.
>
> In general the C++ language is designed around value semantics (i.e.
> construct and move) but has pretty poor support for inplace construction =
of
> immobile types. There are many (I would argue artificial) holes in the
> language and library when you need to work with immobile types.
>
>
>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--001a1143dda0a7264a051f6a918b
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
hu, Sep 10, 2015 at 9:34 AM, Matthew Fioravante <span dir=3D"ltr"><<a hr=
ef=3D"mailto:fmatthew5876@gmail.com" target=3D"_blank">fmatthew5876@gmail.c=
om</a>></span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"marg=
in:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"=
><span class=3D""><br>On Thursday, September 10, 2015 at 1:24:56 AM UTC-4, =
David Krauss wrote:<blockquote style=3D"margin:0px 0px 0px 0.8ex;padding-le=
ft:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-left=
-style:solid" class=3D"gmail_quote">
<br>>=20
<br>> still doesn't work because even there, a semantic check for co=
py/move
<br>> is performed.
<br>
<br>Right. I don=E2=80=99t favor that stylistically, but I=E2=80=99ll take =
it if it can=E2=80=99t be surgically separated from non-movable factory fun=
ctions which are a hole in the language.
<br></blockquote></span><div><br>I=C2=A0would love to have factory function=
s for non-movable types.</div></div></blockquote><div><br></div><div>struct=
Immovable {</div><div>=C2=A0 Immovable(int, int);</div><div>=C2=A0 Immovab=
le(const Immovable&) =3D delete;</div><div>=C2=A0 void operator=3D(cons=
t Immovable&) =3D delete;</div><div>};</div><div><br></div><div>Immovab=
le factory() {</div><div>=C2=A0 return {1, 2};</div><div>}</div><div><br></=
div><div>auto &&val =3D factory();</div><div><br></div><blockquote =
class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid=
;padding-left:1ex"><div dir=3D"ltr"><div>It seems that with=C2=A0return val=
ue optimization,=C2=A0most of the work is already </div><div>done.=C2=A0Unf=
ortunately I think adding support would require new syntax of some kind.</d=
iv><div>=C2=A0</div><div>Maybe an attribute [[emplace]]. This would force R=
VO, enabling support for "returning" a non-movable object and als=
o allowing the programmer to enforce that RVO is used for functions which r=
eturn movable types.</div><div>=C2=A0</div><div><div style=3D"border:1px so=
lid rgb(187,187,187);word-wrap:break-word;background-color:rgb(250,250,250)=
"><code><div><span style=3D"color:rgb(102,102,0)">[[</span><span style=3D"c=
olor:rgb(0,0,0)">emplace</span><span style=3D"color:rgb(102,102,0)">]]</spa=
n><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,0,1=
02)">Widget</span><span style=3D"color:rgb(0,0,0)"> makeWidget</span><span =
style=3D"color:rgb(102,102,0)">()</span><span style=3D"color:rgb(0,0,0)"> <=
/span><span style=3D"color:rgb(102,102,0)">{</span><span style=3D"color:rgb=
(0,0,0)"> </span><span style=3D"color:rgb(0,0,136)">return</span><span styl=
e=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,0,102)">Widget<=
/span><span style=3D"color:rgb(102,102,0)">();</span><span style=3D"color:r=
gb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">}</span><span style=
=3D"color:rgb(0,0,0)"><br></span><span style=3D"color:rgb(102,102,0)">[[</s=
pan><span style=3D"color:rgb(0,0,0)">emplace</span><span style=3D"color:rgb=
(102,102,0)">]]</span><span style=3D"color:rgb(0,0,0)"> </span><span style=
=3D"color:rgb(0,0,136)">auto</span><span style=3D"color:rgb(0,0,0)"> x </sp=
an><span style=3D"color:rgb(102,102,0)">=3D</span><span style=3D"color:rgb(=
0,0,0)"> makeWidget</span><span style=3D"color:rgb(102,102,0)">();</span><s=
pan style=3D"color:rgb(0,0,0)"><br></span><span style=3D"color:rgb(102,102,=
0)">[[</span><span style=3D"color:rgb(0,0,0)">emplace</span><span style=3D"=
color:rgb(102,102,0)">]]</span><span style=3D"color:rgb(0,0,0)"> </span><sp=
an style=3D"color:rgb(0,0,136)">auto</span><span style=3D"color:rgb(0,0,0)"=
> x </span><span style=3D"color:rgb(102,102,0)">=3D</span><span style=3D"co=
lor:rgb(0,0,0)"> std</span><span style=3D"color:rgb(102,102,0)">::</span><s=
pan style=3D"color:rgb(0,0,0)">atomic</span><span style=3D"color:rgb(0,136,=
0)"><int></span><span style=3D"color:rgb(102,102,0)">{};</span><span =
style=3D"color:rgb(0,0,0)"><br></span></div></code></div></div><div>=C2=A0<=
/div><div>Of course with that approach people might just end up sprinkling =
[[emplace]]=C2=A0in all of their functions=C2=A0to optimize and increase co=
mpatibility...</div><div>=C2=A0</div><div>Another option could be a new &qu=
ot;inplace" initialization operator to use instead of =3D. I don't=
have a=C2=A0full specification for such a thing but it=C2=A0might look som=
ething like this:</div><code><div style=3D"border:1px solid rgb(187,187,187=
);word-wrap:break-word;background-color:rgb(250,250,250)"><div>static_asser=
t(is_movable<Widget>::value =3D=3D false);<br><br>Widget makeWidget()=
<=3D; //Declare an inplace return function that must do RVO.<br>auto w =
<=3D makeWidget(); //inplace construct w<br>auto i <=3D std::atomic&l=
t;int>{}; //inplace construct i</div></div></code><div style=3D"border:1=
px solid rgb(187,187,187);word-wrap:break-word;background-color:rgb(250,250=
,250)"><div></div></div><div>=C2=A0</div><div>Such an operator could even b=
e used for value semantic types to specify the specific intent of direct co=
nstruction vs copying. Op <=3D is a strawman for bikeshedding, but I thi=
nk it could work since the comparison <=3D doesn't make sense in a n=
ew variable declaration or function signature.</div><div>=C2=A0</div><div>I=
n general the C++ language is designed around value semantics (i.e. constru=
ct and move) but has pretty poor support for inplace construction of immobi=
le types. There are many (I would argue artificial) holes in the language a=
nd library when you need to work with immobile types.</div><div>=C2=A0</div=
><div>=C2=A0</div></div><div class=3D"HOEnZb"><div class=3D"h5">
<p></p>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--001a1143dda0a7264a051f6a918b--
.
Author: David Krauss <potswa@gmail.com>
Date: Fri, 11 Sep 2015 04:56:34 +0800
Raw View
--Apple-Mail=_A1292610-1E1E-4939-B383-21EBEB055BB5
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
> On 2015=E2=80=9309=E2=80=9311, at 4:37 AM, Richard Smith <richard@metafoo=
..co.uk> wrote:
>=20
> struct Immovable {
> Immovable(int, int);
This should be explicit. After all, it=E2=80=99s not a value-semantic class=
..
> Immovable(const Immovable&) =3D delete;
> void operator=3D(const Immovable&) =3D delete;
> };
>=20
> Immovable factory() {
> return {1, 2};
Omitting Immovable from this line is exactly wrong.
> }
>=20
> auto &&val =3D factory();
Lifetime extension only works for scoped variables.
struct caps {
Immovable member { factory() };
Immovable * ptr =3D new Immovable { factory() };
};
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--Apple-Mail=_A1292610-1E1E-4939-B383-21EBEB055BB5
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2015=E2=80=9309=
=E2=80=9311, at 4:37 AM, Richard Smith <<a href=3D"mailto:richard@metafo=
o.co.uk" class=3D"">richard@metafoo.co.uk</a>> wrote:</div><br class=3D"=
Apple-interchange-newline"><div class=3D""><div style=3D"font-family: Helve=
tica; font-size: 12px; font-style: normal; font-variant: normal; font-weigh=
t: normal; letter-spacing: normal; line-height: normal; orphans: auto; text=
-align: start; text-indent: 0px; text-transform: none; white-space: normal;=
widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=3D=
"">struct Immovable {</div><div style=3D"font-family: Helvetica; font-size:=
12px; font-style: normal; font-variant: normal; font-weight: normal; lette=
r-spacing: normal; line-height: normal; orphans: auto; text-align: start; t=
ext-indent: 0px; text-transform: none; white-space: normal; widows: auto; w=
ord-spacing: 0px; -webkit-text-stroke-width: 0px;" class=3D""> Immova=
ble(int, int);</div></div></blockquote><div><br class=3D""></div><div>This =
should be <font face=3D"Courier" class=3D"">explicit</font>. After all=
, it=E2=80=99s not a value-semantic class.</div><br class=3D""><blockquote =
type=3D"cite" class=3D""><div class=3D""><div style=3D"font-family: Helveti=
ca; font-size: 12px; font-style: normal; font-variant: normal; font-weight:=
normal; letter-spacing: normal; line-height: normal; orphans: auto; text-a=
lign: start; text-indent: 0px; text-transform: none; white-space: normal; w=
idows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=3D""=
> Immovable(const Immovable&) =3D delete;</div><div style=3D"font=
-family: Helvetica; font-size: 12px; font-style: normal; font-variant: norm=
al; font-weight: normal; letter-spacing: normal; line-height: normal; orpha=
ns: auto; text-align: start; text-indent: 0px; text-transform: none; white-=
space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: =
0px;" class=3D""> void operator=3D(const Immovable&) =3D delete;<=
/div><div style=3D"font-family: Helvetica; font-size: 12px; font-style: nor=
mal; font-variant: normal; font-weight: normal; letter-spacing: normal; lin=
e-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-=
transform: none; white-space: normal; widows: auto; word-spacing: 0px; -web=
kit-text-stroke-width: 0px;" class=3D"">};</div><div style=3D"font-family: =
Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-=
weight: normal; letter-spacing: normal; line-height: normal; orphans: auto;=
text-align: start; text-indent: 0px; text-transform: none; white-space: no=
rmal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" cla=
ss=3D""><br class=3D""></div><div style=3D"font-family: Helvetica; font-siz=
e: 12px; font-style: normal; font-variant: normal; font-weight: normal; let=
ter-spacing: normal; line-height: normal; orphans: auto; text-align: start;=
text-indent: 0px; text-transform: none; white-space: normal; widows: auto;=
word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=3D"">Immovable f=
actory() {</div><div style=3D"font-family: Helvetica; font-size: 12px; font=
-style: normal; font-variant: normal; font-weight: normal; letter-spacing: =
normal; line-height: normal; orphans: auto; text-align: start; text-indent:=
0px; text-transform: none; white-space: normal; widows: auto; word-spacing=
: 0px; -webkit-text-stroke-width: 0px;" class=3D""> return {1, 2};</d=
iv></div></blockquote><div><br class=3D""></div><div>Omitting <span st=
yle=3D"font-family: Courier;" class=3D"">Immovable</span> from this li=
ne is exactly wrong.</div><br class=3D""><blockquote type=3D"cite" class=3D=
""><div class=3D""><div style=3D"font-family: Helvetica; font-size: 12px; f=
ont-style: normal; font-variant: normal; font-weight: normal; letter-spacin=
g: normal; line-height: normal; orphans: auto; text-align: start; text-inde=
nt: 0px; text-transform: none; white-space: normal; widows: auto; word-spac=
ing: 0px; -webkit-text-stroke-width: 0px;" class=3D"">}</div><div style=3D"=
font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: =
normal; font-weight: normal; letter-spacing: normal; line-height: normal; o=
rphans: auto; text-align: start; text-indent: 0px; text-transform: none; wh=
ite-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-wid=
th: 0px;" class=3D""><br class=3D""></div><div style=3D"font-family: Helvet=
ica; font-size: 12px; font-style: normal; font-variant: normal; font-weight=
: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-=
align: start; text-indent: 0px; text-transform: none; white-space: normal; =
widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=3D"=
">auto &&val =3D factory();</div></div></blockquote></div><br class=
=3D""><div class=3D"">Lifetime extension only works for scoped variables.</=
div><div class=3D""><br class=3D""></div><div class=3D""><font face=3D"Cour=
ier" class=3D"">struct caps {</font></div><div class=3D""><font face=3D"Cou=
rier" class=3D""> Immovable member { factory() };</font></div>=
<div class=3D""><font face=3D"Courier" class=3D""> Immovable *=
ptr =3D new Immovable { factory() };</font></div><div class=3D""><font fac=
e=3D"Courier" class=3D"">};</font></div><div class=3D""><br class=3D""></di=
v></body></html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--Apple-Mail=_A1292610-1E1E-4939-B383-21EBEB055BB5--
.
Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Thu, 10 Sep 2015 14:02:37 -0700
Raw View
--001a1134e2123c7abb051f6aebb7
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Thu, Sep 10, 2015 at 1:37 PM, Richard Smith <richard@metafoo.co.uk>
wrote:
> On Thu, Sep 10, 2015 at 9:34 AM, Matthew Fioravante <
> fmatthew5876@gmail.com> wrote:
>
>>
>> On Thursday, September 10, 2015 at 1:24:56 AM UTC-4, David Krauss wrote:
>>>
>>>
>>> >
>>> > still doesn't work because even there, a semantic check for copy/move
>>> > is performed.
>>>
>>> Right. I don=E2=80=99t favor that stylistically, but I=E2=80=99ll take =
it if it can=E2=80=99t be
>>> surgically separated from non-movable factory functions which are a hol=
e in
>>> the language.
>>>
>>
>> I would love to have factory functions for non-movable types.
>>
>
> struct Immovable {
> Immovable(int, int);
> Immovable(const Immovable&) =3D delete;
> void operator=3D(const Immovable&) =3D delete;
> };
>
> Immovable factory() {
> return {1, 2};
> }
>
> auto &&val =3D factory();
>
Okay, that's twisted!!!
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--001a1134e2123c7abb051f6aebb7
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
hu, Sep 10, 2015 at 1:37 PM, Richard Smith <span dir=3D"ltr"><<a href=3D=
"mailto:richard@metafoo.co.uk" target=3D"_blank">richard@metafoo.co.uk</a>&=
gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 =
0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div c=
lass=3D"gmail_extra"><div class=3D"gmail_quote"><span class=3D"">On Thu, Se=
p 10, 2015 at 9:34 AM, Matthew Fioravante <span dir=3D"ltr"><<a href=3D"=
mailto:fmatthew5876@gmail.com" target=3D"_blank">fmatthew5876@gmail.com</a>=
></span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0=
0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><span=
><br>On Thursday, September 10, 2015 at 1:24:56 AM UTC-4, David Krauss wrot=
e:<blockquote style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-lef=
t-color:rgb(204,204,204);border-left-width:1px;border-left-style:solid" cla=
ss=3D"gmail_quote">
<br>>=20
<br>> still doesn't work because even there, a semantic check for co=
py/move
<br>> is performed.
<br>
<br>Right. I don=E2=80=99t favor that stylistically, but I=E2=80=99ll take =
it if it can=E2=80=99t be surgically separated from non-movable factory fun=
ctions which are a hole in the language.
<br></blockquote></span><div><br>I=C2=A0would love to have factory function=
s for non-movable types.</div></div></blockquote><div><br></div></span><div=
>struct Immovable {</div><div>=C2=A0 Immovable(int, int);</div><div>=C2=A0 =
Immovable(const Immovable&) =3D delete;</div><div>=C2=A0 void operator=
=3D(const Immovable&) =3D delete;</div><div>};</div><div><br></div><div=
>Immovable factory() {</div><div>=C2=A0 return {1, 2};</div><div>}</div><di=
v><br></div><div>auto &&val =3D factory();</div></div></div></div><=
/blockquote><div><br></div><div>Okay, that's twisted!!!</div></div></di=
v></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--001a1134e2123c7abb051f6aebb7--
.
Author: Richard Smith <richard@metafoo.co.uk>
Date: Thu, 10 Sep 2015 14:29:00 -0700
Raw View
--001a114258789ab517051f6b4996
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Thu, Sep 10, 2015 at 1:56 PM, David Krauss <potswa@gmail.com> wrote:
>
> On 2015=E2=80=9309=E2=80=9311, at 4:37 AM, Richard Smith <richard@metafoo=
..co.uk> wrote:
>
> struct Immovable {
> Immovable(int, int);
>
>
> This should be explicit. After all, it=E2=80=99s not a value-semantic cla=
ss.
>
That is not the criterion I use for this decision. The question is, does
the pair of ints describe the value of the object (implicit constructor) or
does it describe a set of inputs to a /computation/ that will produce the
value of the object (explicit constructor)?
> Immovable(const Immovable&) =3D delete;
> void operator=3D(const Immovable&) =3D delete;
> };
>
> Immovable factory() {
> return {1, 2};
>
>
> Omitting Immovable from this line is exactly wrong.
>
That's just, like, your opinion, man. =3D)
> }
>
> auto &&val =3D factory();
>
>
> Lifetime extension only works for scoped variables.
>
Yes. Guaranteed copy elision from temporaries would provide a complete
solution (and I might present a paper on that topic at Kona). Then we don't
need those fancy tricks, and we can instead just write the natural code:
Immovable factory() {
return Immovable{1, 2}; // no copy here
}
auto val =3D factory(); // no copy here either
struct caps {
> Immovable member { factory() };
> Immovable * ptr =3D new Immovable { factory() };
> };
>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--001a114258789ab517051f6b4996
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
hu, Sep 10, 2015 at 1:56 PM, David Krauss <span dir=3D"ltr"><<a href=3D"=
mailto:potswa@gmail.com" target=3D"_blank">potswa@gmail.com</a>></span> =
wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bord=
er-left:1px #ccc solid;padding-left:1ex"><div style=3D"word-wrap:break-word=
"><br><div><blockquote type=3D"cite"><div>On 2015=E2=80=9309=E2=80=9311, at=
4:37 AM, Richard Smith <<a href=3D"mailto:richard@metafoo.co.uk" target=
=3D"_blank">richard@metafoo.co.uk</a>> wrote:</div><br><div><div style=
=3D"font-family:Helvetica;font-size:12px;font-style:normal;font-variant:nor=
mal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:=
start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0=
px">struct Immovable {</div><div style=3D"font-family:Helvetica;font-size:1=
2px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing=
:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:=
none;white-space:normal;word-spacing:0px">=C2=A0 Immovable(int, int);</div>=
</div></blockquote><div><br></div><div>This should be=C2=A0<font face=3D"Co=
urier">explicit</font>. After all, it=E2=80=99s not a value-semantic class.=
</div></div></div></blockquote><div><br></div><div>That is not the criterio=
n I use for this decision. The question is, does the pair of ints describe =
the value of the object (implicit constructor) or does it describe a set of=
inputs to a /computation/ that will produce the value of the object (expli=
cit constructor)?</div><blockquote class=3D"gmail_quote" style=3D"margin:0 =
0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style=3D"word-wr=
ap:break-word"><div><span class=3D""><blockquote type=3D"cite"><div><div st=
yle=3D"font-family:Helvetica;font-size:12px;font-style:normal;font-variant:=
normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-ali=
gn:start;text-indent:0px;text-transform:none;white-space:normal;word-spacin=
g:0px">=C2=A0 Immovable(const Immovable&) =3D delete;</div><div style=
=3D"font-family:Helvetica;font-size:12px;font-style:normal;font-variant:nor=
mal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:=
start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0=
px">=C2=A0 void operator=3D(const Immovable&) =3D delete;</div><div sty=
le=3D"font-family:Helvetica;font-size:12px;font-style:normal;font-variant:n=
ormal;font-weight:normal;letter-spacing:normal;line-height:normal;text-alig=
n:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing=
:0px">};</div><div style=3D"font-family:Helvetica;font-size:12px;font-style=
:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-h=
eight:normal;text-align:start;text-indent:0px;text-transform:none;white-spa=
ce:normal;word-spacing:0px"><br></div><div style=3D"font-family:Helvetica;f=
ont-size:12px;font-style:normal;font-variant:normal;font-weight:normal;lett=
er-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-=
transform:none;white-space:normal;word-spacing:0px">Immovable factory() {</=
div><div style=3D"font-family:Helvetica;font-size:12px;font-style:normal;fo=
nt-variant:normal;font-weight:normal;letter-spacing:normal;line-height:norm=
al;text-align:start;text-indent:0px;text-transform:none;white-space:normal;=
word-spacing:0px">=C2=A0 return {1, 2};</div></div></blockquote><div><br></=
div></span><div>Omitting=C2=A0<span style=3D"font-family:Courier">Immovable=
</span>=C2=A0from this line is exactly wrong.</div></div></div></blockquote=
><div><br></div><div>=C2=A0That's just, like, your opinion, man. =3D)</=
div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-lef=
t:1px #ccc solid;padding-left:1ex"><div style=3D"word-wrap:break-word"><div=
><blockquote type=3D"cite"><div><div style=3D"font-family:Helvetica;font-si=
ze:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spa=
cing:normal;line-height:normal;text-align:start;text-indent:0px;text-transf=
orm:none;white-space:normal;word-spacing:0px">}</div><div style=3D"font-fam=
ily:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-wei=
ght:normal;letter-spacing:normal;line-height:normal;text-align:start;text-i=
ndent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></di=
v><div style=3D"font-family:Helvetica;font-size:12px;font-style:normal;font=
-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal=
;text-align:start;text-indent:0px;text-transform:none;white-space:normal;wo=
rd-spacing:0px">auto &&val =3D factory();</div></div></blockquote><=
/div><br><div>Lifetime extension only works for scoped variables.</div></di=
v></blockquote><div><br></div><div>Yes. Guaranteed copy elision from tempor=
aries would provide a complete solution (and I might present a paper on tha=
t topic at Kona). Then we don't need those fancy tricks, and we can ins=
tead just write the natural code:</div><div><br></div><div>=C2=A0 Immovable=
factory() {</div><div>=C2=A0 =C2=A0 return Immovable{1, 2}; // no copy her=
e</div><div>=C2=A0 }</div><div>=C2=A0 auto val =3D factory(); // no copy he=
re either</div><div><br></div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style=3D"=
word-wrap:break-word"><div><font face=3D"Courier">struct caps {</font></div=
><div><font face=3D"Courier">=C2=A0 =C2=A0 Immovable member { factory() };<=
/font></div><div><font face=3D"Courier">=C2=A0 =C2=A0 Immovable * ptr =3D n=
ew Immovable { factory() };</font></div><div><font face=3D"Courier">};</fon=
t></div><div><br></div></div><div class=3D"HOEnZb"><div class=3D"h5">
<p></p>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--001a114258789ab517051f6b4996--
.
Author: David Krauss <potswa@gmail.com>
Date: Fri, 11 Sep 2015 09:57:35 +0800
Raw View
--Apple-Mail=_5C4A5E00-7BAC-40A1-B1EB-63CB428CBAA7
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
> On 2015=E2=80=9309=E2=80=9311, at 5:29 AM, Richard Smith <richard@metafoo=
..co.uk> wrote:
>=20
> On Thu, Sep 10, 2015 at 1:56 PM, David Krauss <potswa@gmail.com <mailto:p=
otswa@gmail.com>> wrote:
>=20
> This should be explicit. After all, it=E2=80=99s not a value-semantic cla=
ss.
>=20
> That is not the criterion I use for this decision. The question is, does =
the pair of ints describe the value of the object (implicit constructor) or=
does it describe a set of inputs to a /computation/ that will produce the =
value of the object (explicit constructor)?
>=20
> That's just, like, your opinion, man. =3D)
That was meant as a reference my first message. Value semantics are a bit s=
ubjective, but they=E2=80=99re anti-correlated with a deleted move construc=
tor.
If you can=E2=80=99t have this:
Immovable do_ =3D Immovable{ 2, 2 };
then how can this be allowed?
Immovable do_ =3D { 2, 2 };
The only conceptual wiggle room is the fleeting idea that the list itself i=
s a value.
> Yes. Guaranteed copy elision from temporaries would provide a complete so=
lution (and I might present a paper on that topic at Kona). Then we don't n=
eed those fancy tricks, and we can instead just write the natural code:
Hooray! Let me know if I can help.
> Immovable factory() {
> return Immovable{1, 2}; // no copy here
> }
> auto val =3D factory(); // no copy here either
Hmm, should that be allowed with copy-initialization, or should auto val{ f=
actory() } be required?
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--Apple-Mail=_5C4A5E00-7BAC-40A1-B1EB-63CB428CBAA7
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2015=E2=80=9309=
=E2=80=9311, at 5:29 AM, Richard Smith <<a href=3D"mailto:richard@metafo=
o.co.uk" class=3D"">richard@metafoo.co.uk</a>> wrote:</div><br class=3D"=
Apple-interchange-newline"><div class=3D""><div dir=3D"ltr" class=3D""><div=
class=3D"gmail_extra"><div class=3D"gmail_quote">On Thu, Sep 10, 2015 at 1=
:56 PM, David Krauss <span dir=3D"ltr" class=3D""><<a href=3D"mailto:pot=
swa@gmail.com" target=3D"_blank" class=3D"">potswa@gmail.com</a>></span>=
wrote:<br class=3D""><blockquote class=3D"gmail_quote" style=3D"margin:0 0=
0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style=3D"word-wra=
p:break-word" class=3D""><br class=3D""><div class=3D""><div class=3D"">Thi=
s should be <font face=3D"Courier" class=3D"">explicit</font>. After a=
ll, it=E2=80=99s not a value-semantic class.</div></div></div></blockquote>=
<div class=3D""><br class=3D""></div><div class=3D"">That is not the criter=
ion I use for this decision. The question is, does the pair of ints describ=
e the value of the object (implicit constructor) or does it describe a set =
of inputs to a /computation/ that will produce the value of the object (exp=
licit constructor)?</div><div class=3D""><br class=3D""></div><div class=3D=
"">That's just, like, your opinion, man. =3D)</div></div></div></div></div>=
</blockquote><div><br class=3D""></div><div>That was meant as a reference m=
y first message. Value semantics are a bit subjective, but they=E2=80=99re =
anti-correlated with a deleted move constructor.</div><div><br class=3D""><=
/div><div>If you can=E2=80=99t have this:</div><div><br class=3D""></div><d=
iv><font face=3D"Courier" class=3D"">Immovable do_ =3D Immovable{ 2, 2 };</=
font></div><div><br class=3D""></div><div>then how can this be allowed?</di=
v><div><br class=3D""></div><div><div><font face=3D"Courier" class=3D"">Imm=
ovable do_ =3D { 2, 2 };</font></div></div><div><br class=3D""></div><div>T=
he only conceptual wiggle room is the fleeting idea that the list itself is=
a value.</div><br class=3D""><blockquote type=3D"cite" class=3D""><div cla=
ss=3D""><div dir=3D"ltr" class=3D""><div class=3D"gmail_extra"><div class=
=3D"gmail_quote"><div class=3D"">Yes. Guaranteed copy elision from temporar=
ies would provide a complete solution (and I might present a paper on that =
topic at Kona). Then we don't need those fancy tricks, and we can instead j=
ust write the natural code:</div><div class=3D""></div></div></div></div></=
div></blockquote><div><br class=3D""></div><div>Hooray! Let me know if I ca=
n help.</div><br class=3D""><blockquote type=3D"cite" class=3D""><div class=
=3D""><div dir=3D"ltr" class=3D""><div class=3D"gmail_extra"><div class=3D"=
gmail_quote"><div class=3D""> Immovable factory() {</div><div class=
=3D""> return Immovable{1, 2}; // no copy here</div><div class=
=3D""> }</div><div class=3D""> auto val =3D factory(); // no co=
py here either</div></div></div></div></div></blockquote><br class=3D""></d=
iv>Hmm, should that be allowed with copy-initialization, or should <font fa=
ce=3D"Courier" class=3D"">auto val{ factory() }</font> be required?<div cla=
ss=3D""><br class=3D""></div></body></html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--Apple-Mail=_5C4A5E00-7BAC-40A1-B1EB-63CB428CBAA7--
.
Author: Richard Smith <richard@metafoo.co.uk>
Date: Thu, 10 Sep 2015 19:03:27 -0700
Raw View
--001a114258781fe062051f6f1fe3
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Thu, Sep 10, 2015 at 6:57 PM, David Krauss <potswa@gmail.com> wrote:
>
> On 2015=E2=80=9309=E2=80=9311, at 5:29 AM, Richard Smith <richard@metafoo=
..co.uk> wrote:
>
> On Thu, Sep 10, 2015 at 1:56 PM, David Krauss <potswa@gmail.com> wrote:
>
>>
>> This should be explicit. After all, it=E2=80=99s not a value-semantic cl=
ass.
>>
>
> That is not the criterion I use for this decision. The question is, does
> the pair of ints describe the value of the object (implicit constructor) =
or
> does it describe a set of inputs to a /computation/ that will produce the
> value of the object (explicit constructor)?
>
> That's just, like, your opinion, man. =3D)
>
>
> That was meant as a reference my first message. Value semantics are a bit
> subjective, but they=E2=80=99re anti-correlated with a deleted move const=
ructor.
>
> If you can=E2=80=99t have this:
>
> Immovable do_ =3D Immovable{ 2, 2 };
>
> then how can this be allowed?
>
> Immovable do_ =3D { 2, 2 };
>
> The only conceptual wiggle room is the fleeting idea that the list itself
> is a value.
>
> Yes. Guaranteed copy elision from temporaries would provide a complete
> solution (and I might present a paper on that topic at Kona). Then we don=
't
> need those fancy tricks, and we can instead just write the natural code:
>
>
> Hooray! Let me know if I can help.
>
I'll let you know once I have a draft.
> Immovable factory() {
> return Immovable{1, 2}; // no copy here
> }
> auto val =3D factory(); // no copy here either
>
>
> Hmm, should that be allowed with copy-initialization, or should auto val{
> factory() } be required?
>
With the approach I'm intending to follow, that will be valid (and that
seems necessary, given that 'return', argument passing, braced init lists,
and so on all use copy-initialization).
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--001a114258781fe062051f6f1fe3
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
hu, Sep 10, 2015 at 6:57 PM, David Krauss <span dir=3D"ltr"><<a href=3D"=
mailto:potswa@gmail.com" target=3D"_blank">potswa@gmail.com</a>></span> =
wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bord=
er-left:1px #ccc solid;padding-left:1ex"><div style=3D"word-wrap:break-word=
"><br><div><blockquote type=3D"cite"><span class=3D""><div>On 2015=E2=80=93=
09=E2=80=9311, at 5:29 AM, Richard Smith <<a href=3D"mailto:richard@meta=
foo.co.uk" target=3D"_blank">richard@metafoo.co.uk</a>> wrote:</div><br>=
</span><div><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail=
_quote"><span class=3D"">On Thu, Sep 10, 2015 at 1:56 PM, David Krauss <spa=
n dir=3D"ltr"><<a href=3D"mailto:potswa@gmail.com" target=3D"_blank">pot=
swa@gmail.com</a>></span> wrote:<br></span><span class=3D""><blockquote =
class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid=
;padding-left:1ex"><div style=3D"word-wrap:break-word"><br><div><div>This s=
hould be=C2=A0<font face=3D"Courier">explicit</font>. After all, it=E2=80=
=99s not a value-semantic class.</div></div></div></blockquote><div><br></d=
iv><div>That is not the criterion I use for this decision. The question is,=
does the pair of ints describe the value of the object (implicit construct=
or) or does it describe a set of inputs to a /computation/ that will produc=
e the value of the object (explicit constructor)?</div><div><br></div></spa=
n><span class=3D""><div>That's just, like, your opinion, man. =3D)</div=
></span></div></div></div></div></blockquote><div><br></div><div>That was m=
eant as a reference my first message. Value semantics are a bit subjective,=
but they=E2=80=99re anti-correlated with a deleted move constructor.</div>=
<div><br></div><div>If you can=E2=80=99t have this:</div><div><br></div><di=
v><font face=3D"Courier">Immovable do_ =3D Immovable{ 2, 2 };</font></div><=
div><br></div><div>then how can this be allowed?</div><div><br></div><div><=
div><font face=3D"Courier">Immovable do_ =3D { 2, 2 };</font></div></div><d=
iv><br></div><div>The only conceptual wiggle room is the fleeting idea that=
the list itself is a value.</div><span class=3D""><br><blockquote type=3D"=
cite"><div><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_=
quote"><div>Yes. Guaranteed copy elision from temporaries would provide a c=
omplete solution (and I might present a paper on that topic at Kona). Then =
we don't need those fancy tricks, and we can instead just write the nat=
ural code:</div><div></div></div></div></div></div></blockquote><div><br></=
div></span><div>Hooray! Let me know if I can help.</div></div></div></block=
quote><div><br></div><div>I'll let you know once I have a draft.=C2=A0<=
/div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-le=
ft:1px #ccc solid;padding-left:1ex"><div style=3D"word-wrap:break-word"><di=
v><span class=3D""><blockquote type=3D"cite"><div><div dir=3D"ltr"><div cla=
ss=3D"gmail_extra"><div class=3D"gmail_quote"><div>=C2=A0 Immovable factory=
() {</div><div>=C2=A0 =C2=A0 return Immovable{1, 2}; // no copy here</div><=
div>=C2=A0 }</div><div>=C2=A0 auto val =3D factory(); // no copy here eithe=
r</div></div></div></div></div></blockquote><br></span></div>Hmm, should th=
at be allowed with copy-initialization, or should <font face=3D"Courier">au=
to val{ factory() }</font> be required?</div></blockquote><div><br></div><d=
iv>With the approach I'm intending to follow, that will be valid (and t=
hat seems necessary, given that 'return', argument passing, braced =
init lists, and so on all use copy-initialization).</div></div></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--001a114258781fe062051f6f1fe3--
.
Author: David Krauss <potswa@gmail.com>
Date: Fri, 11 Sep 2015 10:22:38 +0800
Raw View
--Apple-Mail=_4EA365B9-9802-4762-B219-F79F1C29F571
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
> On 2015=E2=80=9309=E2=80=9311, at 10:03 AM, Richard Smith <richard@metafo=
o.co.uk> wrote:
>=20
> With the approach I'm intending to follow, that will be valid (and that s=
eems necessary, given that 'return', argument passing, braced init lists, a=
nd so on all use copy-initialization).
When there=E2=80=99s no equals sign (passing, returning, throwing), it migh=
t as well be direct-initialization:
> The problem with copy-initialization is that it=E2=80=99s sometimes used =
with no equals sign, such as in passing, returning, and throwing. The langu=
age treats it as a conservative choice when it=E2=80=99s impossible to guar=
antee that two values are the same object. However, this guarantee can alwa=
ys be made when passing, throwing, or returning a prvalue. The language/ABI=
interface is interfering with the programmer=E2=80=99s stated intentions.
My guess at the rationale for copy-initialization being applied in those co=
ntexts is that the implementation detail of a copy might be required. But i=
f we change that detail, the backwards application of syntax-oriented seman=
tics might also change.
I might not ready to argue this in court, though :P .
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--Apple-Mail=_4EA365B9-9802-4762-B219-F79F1C29F571
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2015=E2=80=9309=
=E2=80=9311, at 10:03 AM, Richard Smith <<a href=3D"mailto:richard@metaf=
oo.co.uk" class=3D"">richard@metafoo.co.uk</a>> wrote:</div><br class=3D=
"Apple-interchange-newline"><div class=3D""><div dir=3D"ltr" style=3D"font-=
family: Helvetica; font-size: 12px; font-style: normal; font-variant: norma=
l; font-weight: normal; letter-spacing: normal; line-height: normal; orphan=
s: auto; text-align: start; text-indent: 0px; text-transform: none; white-s=
pace: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0=
px;" class=3D""><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div =
class=3D"">With the approach I'm intending to follow, that will be valid (a=
nd that seems necessary, given that 'return', argument passing, braced init=
lists, and so on all use copy-initialization).</div></div></div></div></di=
v></blockquote><br class=3D""></div><div>When there=E2=80=99s no equals sig=
n (passing, returning, throwing), it might as well be direct-initialization=
:</div><div><br class=3D""></div><div><blockquote type=3D"cite" class=3D"">=
<div class=3D""><div class=3D"">The problem with copy-initialization is tha=
t it=E2=80=99s sometimes used with no equals sign, such as in passing, retu=
rning, and throwing. The language treats it as a conservative choice when i=
t=E2=80=99s impossible to guarantee that two values are the same object. Ho=
wever, this guarantee <i class=3D"">can</i> always be made when p=
assing, throwing, or returning a prvalue. The language/ABI interface is int=
erfering with the programmer=E2=80=99s stated intentions.</div></div></bloc=
kquote></div><br class=3D""><div class=3D"">My guess at the rationale for c=
opy-initialization being applied in those contexts is that the implementati=
on detail of a copy might be required. But if we change that detail, the ba=
ckwards application of syntax-oriented semantics might also change.</div><d=
iv class=3D""><br class=3D""></div><div class=3D"">I might not ready to arg=
ue this in court, though :P .</div><div class=3D""><br class=3D""></div></b=
ody></html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--Apple-Mail=_4EA365B9-9802-4762-B219-F79F1C29F571--
.
Author: "Mark A. Gibbs" <indi.in.the.wired@gmail.com>
Date: Thu, 10 Sep 2015 21:02:11 -0700 (PDT)
Raw View
------=_Part_164_706540651.1441944131497
Content-Type: multipart/alternative;
boundary="----=_Part_165_1303164199.1441944131499"
------=_Part_165_1303164199.1441944131499
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Wednesday, 9 September 2015 22:53:52 UTC-4, David Krauss wrote:
>
> Elision hasn=E2=80=99t been mentioned yet :( .
>
=20
The first 3/4 of the original post was just a whirlwind rush through the=20
rationale of why I'm proposing what I'm proposing, haphazardly glossing=20
over numerous and sundry details that aren't really relevant. To reiterate=
=20
the reasoning:
- There are myriad ways to define new objects.
- Every one of those ways has at least one fail case or gotcha.
- Most of the ways cannot be salvaged - the fail case or gotcha cannot=
=20
be fixed without creating other headaches.
- But there is one way that is almost perfect, and for which a fix is=20
plausible: the form "XXX x =3D YYY{...};", where "XXX" and "YYY" resolve=
=20
to exactly the same type. (You can replace the braces with parentheses,=
=20
too.)
- The only gotcha in that case is that it doesn't work for non-movable=
=20
and non-copyable types (though it does work for non-movable/copyable and=
=20
movable/non-copyable types).
- What makes this gotcha even more absurd is that, in reality, no move=
=20
or copy ever happens, due to elision.
- This elision, which changes the observable behaviour of the program,=
=20
is allowed by the standard, but not required... and this is why that for=
m=20
doesn't work for non-movable/non-copyable types.
- So what my proposal is, is make that elision "mandatory", in effect -=
=20
or rather, reinterpret statements of the form "XXX x =3D YYY{...};" to b=
e=20
a "definition statement", which is identical in meaning to "YYY x{...};"=
=20
(or you can substitute parentheses, and you won't get bitten by the MVP)=
..=20
In other words, making it a new form of direct construction expression.
- What this proposal does is:
- Gives us one perfect way to direct define/define new variables that=
=20
works in all contexts, all the time, generic or not, no exceptions.
- With a syntax that is easy to understand, clear, familiar and=20
consistent with other types of construction (such as copy/move/conver=
sion=20
construction "XXX x =3D val;").
- With all the flexibility you can possibly want (you can use braces=
=20
or parentheses, as you please, and they will select list constructors=
or=20
not as per current rules).
- Without breaking any currently legal code.
=20
Note that this has nothing to do with factory functions - whether for=20
non-value types or not - and so is unrelated to the discussion going on=20
elsewhere.
Writing random code from no semantic premises, and guessing at meaning from=
=20
> the perspective of a naive person, is not part of language design.
>
> The solution to this problem is that newbies shouldn=E2=80=99t write=20
> non-value-semantic classes. Deleting the move constructor is a red flag,=
=20
> indicating that programming assistance is needed.
>
> (Snip =E2=80=94 the newbie did not seek help. This seldom ends well in an=
y=20
> language.)
>
Most of my best students are those who took the initiative to figure things=
=20
out in the language via experimentation. When you can't do that - or worse,=
=20
as in this situation, when experimentation leads you confidently to the=20
wrong answer - that means the language simply doesn't make sense. I don't=
=20
think the correct answer to that dilemma is "you shouldn't experiment". The=
=20
problem is not the student, it's the language.
Nothing rules out consulting an expert, of course, but the point is that=20
you have to know *when* to consult an expert, and what questions to ask.=20
You can't simply walk up to a language expert and say "just tell me=20
everything". All experts and help communities expect you to do your=20
homework and come prepared only with those questions you can't figure out=
=20
on your own. (And in this case, trying to figure it out on your own will=20
lead you to the wrong answer. Thus, we have a problem.)
Actually, making the language make more sense to beginners is my primary=20
motivation for proposing this change (but also, easier generic=20
programming). I would love to be able to tell the people I teach, on day 1=
=20
with no hemming or hawing or qualification: "This is how you create a new=
=20
object in C++. Just do this. Auto, name, equals, type, braces, semicolon.=
=20
Done. Want to initialize with a specific value? Stick it in the braces.=20
Yes, there are other ways that you'll certainly see in other people's code,=
=20
and in time - when we cover more topics - we'll talk about the various=20
pros, cons, and gotchas. For now, just do this. It works." Then I can move=
=20
on to teaching them actually useful things, and not have them come up to me=
=20
a couple days later, "um, I tried to use this lock guard, and...".
Simple things should be simple. There doesn't need to be a goblin lurking=
=20
in every single corner of the language.
=20
> And BTW, I agree with Ville=E2=80=99s that your proposal is closely align=
ed with=20
> N4014. They both result from blaming the problems of non-value-semantic=
=20
> classes on the equals sign instead of the class. The equals sign is a=20
> safety mechanism to protect you from thorny types; getting rid of its=20
> significance will only open the gates to more nastiness.
>
Okay, I think I'm cluing in to what you and Ville are saying. When=20
referring to the relationship to N4014, you are not actually referring to=
=20
the actual content of the paper (or the note on why it was rejected), but=
=20
rather to what I assume is a discussion that went on behind the scenes.=20
That discussion was not just on the specific issue (of explicitness), but a=
=20
broader discussion about protecting the purity of separation between value=
=20
types and non-value types.
And I gather what you're saying is that you want the equals sign to be the=
=20
line of separation between value types and non-value types - that is, when=
=20
you're using an equal sign, you must be working with a value type.
Does that correctly summarize what you and Ville are getting at?
Assuming so, I have to disagree with the reasoning. I don't disagree with=
=20
maintaining a bright line of separation between value types and non-value=
=20
types (let's just go with VTs and NVTs) - what I disagree with is that the=
=20
equal sign is worth defending for this cause. I would say that battle is=20
over, and purity lost. Here's why:
atomic<int> x =3D {};
That works, but this doesn't:
atomic<int> x =3D atomic<int>{};
So logically that means that the first statement is not really constructing=
=20
an atomic on the right - it's (in essence) assigning (which is really a=20
conversion construction) the (empty) list object on the right to the atomic=
=20
on the left.
But if that's so, then why doesn't it work with types with an explicit=20
default constructor?
The fact that it fails when the constructor is explicit implies that there=
=20
must be (implicitly) an atomic<int> construction going on on the right. I=
=20
mean, you can't sanely argue that whatever is being constructed on the left=
=20
isn't explicitly an atomic<int>, right?
Yet if that is what is happening, then why does the second form fail? Isn't=
=20
it doing exactly the same thing. Only... *wince*... explicitly?
So the equal sign is already in a dire mess when it comes to drawing a=20
bright line between VTs and NVTs. Digging in and defending it for that=20
purpose seems quixotic.
I also don't see any point in blaming NVTs for the mess, and saying "types=
=20
should always be VTs... except when they can't possibly, and in that case,=
=20
damn them to hell". Or rather, "yes, this is a mess, but it's only a mess=
=20
when you use NVTs, so don't use them... unless you really, really have to,=
=20
and if you have to, well, just suck up and accept the pain" (which reminds=
=20
me of that old joke about the doctor and "it hurts when I do this"). I do=
=20
agree that you should strongly prefer value semantics for your types, but=
=20
the reality is that there are types for which that simply doesn't work, and=
=20
those types aren't exactly rare or obscure. (You can make a valid argument=
=20
against using mutexes and atomics all over the place - and maybe even locks=
=20
- because there are better options for concurrency and parallelism, but=20
what about scope guard objects? Like things that manage commit-or-rollback=
=20
for transaction-like operations.) Creating one universal way to create=20
objects really doesn't open the floodgates to making NVTs generally easy to=
=20
use. After all, if your coding standard specified always using non-auto=20
copy-/direct-list-initialization, that ship's already sailed anyway.
What I'm proposing is to change the way you think about the equal sign in=
=20
expressions of the form "XXX x =3D YYY{...};". Don't think of it as an=20
assignment operation (which, frankly, it already isn't - it doesn't call=20
any assignment operation, it does a (copy/move) construction). Think of it=
=20
not as a mathematical "equality" (which it already isn't really) but rather=
=20
as a "definition". Mentally replace it not with "takes the value of", but=
=20
rather "is".
And there is precedence for this in C++.
// This is not an operation on values
using type =3D other_type;
// Neither is this
namespace ns =3D verbose::name::space;
In other words, in the context of statements of the form "XXX x =3D YYY{...=
};",=20
where "XXX" and "YYY" resolve to exactly the same type, the equals doesn't=
=20
describe a transmission of value, but rather an alias. You can view it as=
=20
defining a label "x", which is interpreted as a "YYY" object (remember, "XX=
X"=20
resolves to the exact same type, but "XXX" might be "auto" whereas "YYY"=20
cannot be), that is bound to the temporary that is created on the right,=20
and the lifetime of the temporary is extended for the lifetime of the label=
=20
"x".
And this form of variable definition is not revolutionary. Many languages=
=20
have similar constructs
// Perl
my $x =3D initializer;
// OCaml, Rust
let x =3D initializer;
// JavaScript, Swift
var x =3D initializer;
// C++, conceptually
auto x =3D initializer;
Obviously the circumstances are very different in those other languages,=20
and I'm not suggesting the semantics be duplicated in C++. I'm just saying=
=20
the form is familiar. It just "looks like" you're creating the object on=20
the left, and describing an alias to it on the right.
Another side effect of this change would be creating a kind of beautiful,=
=20
simplistic consistency in the language. Here is what it would look like if=
=20
you are using explicit types (no "auto"):
type x =3D type{}; // (direct) default construction
type x =3D type(); // same
// Both of the above work for *all* types that have default constructors,
// regardless of whether it's explicit or not, regardless of whether the=20
type
// is movable and/or copyable. It Just Works(tm).
type x =3D type{...}; // (explicit, direct) list initialization
type x =3D type(...); // (explicit, direct) non-list initialization
// Both of the above work for *all* types that have the constructor with th=
e
// given signature, regardless of whether it's explicit or not, regardless=
=20
of
// whether the type is movable and/or copyable. As with today, an=20
initializer
// list constructor gets priority in the first case, and a=20
non-initializer-list
// constructor gets priority in the second case. It Just Works(tm).
type x =3D lvalue; // copy construction (presumably)
type x =3D rvalue; // move construction (presumably)
type x =3D std::move(lvalue); // move construction (presumably)
type x =3D factory_function(); // move construction (presumably)
// The semantics of the above don't change - they only work for types that
// allow copy/move construction. These all Just Work(tm) for value types.
type x =3D 0; // int
type x =3D {0}; // int
// The semantics of the above don't change.
// The type names don't need to be identical, they just need to resolve to=
=20
the
// same type.
using alias =3D type;
alias x =3D type{}; // (direct) default construction
alias x =3D type(); // same
alias x =3D type{...}; // (explicit, direct) list initialization
alias x =3D type(...); // (explicit, direct) non-list initialization
Things get even simpler, and more elegant, when you use "auto":
auto x =3D type{}; // (direct) default construction
auto x =3D type(); // same
// Both of the above work for *all* types that have default constructors,
// regardless of whether it's explicit or not, regardless of whether the=20
type
// is movable and/or copyable. It Just Works(tm).
auto x =3D type{...}; // (explicit, direct) list initialization
auto x =3D type(...); // (explicit, direct) non-list initialization
// Both of the above work for *all* types that have the constructor with th=
e
// given signature, regardless of whether it's explicit or not, regardless=
=20
of
// whether the type is movable and/or copyable. As with today, an=20
initializer
// list constructor gets priority in the first case, and a=20
non-initializer-list
// constructor gets priority in the second case. It Just Works(tm).
auto x =3D lvalue; // copy construction (presumably)
auto x =3D rvalue; // move construction (presumably)
auto x =3D std::move(lvalue); // move construction (presumably)
auto x =3D factory_function(); // move construction (presumably)
// The semantics of the above don't change - they only work for types that
// allow copy/move construction. These all Just Work(tm) for value types.
auto x =3D 0; // int
auto x =3D {0}; // std::initializer_list<int> (with one element, that is 0=
)
// which is different from using explicit type (but still=20
clear)
// The semantics of the above don't change.
// No issues with type aliasing
I can only think of two potential gotchas, but they're both rather esoteric=
=20
cases.
Case 1 is code that relies on the current behaviour:
template <typename T>
auto func()
{
// I expect this template function to only be instantiated for types that=
=20
are
// movable and/or copyable, and rather than expressing this via traits or
// concepts, I'm relying on the current interpretation of the following=
=20
lines:
T t1 =3D T{};
auto t1 =3D T{};
}
This function fails to compile today for non-movable/non-copyable types,=20
but will with my proposed change.
However, I have never seen any code that relied on that, and I would argue=
=20
any code that did was already a maintenance headache.
Case 2 is code that gets bitten by type aliasing:
// assuming type_1 is non-copyable and non-movable
using type_2 =3D type_1;
template <typename T, typename U>
auto func()
{
// I expect this template function to do a default construction of a=20
temporary
// U object, then a conversion construction of a T using that temporary.
// In fact, I *INSIST* on this behaviour, and even use a special=20
compiler, or
// compiler switches, to make it happen.
T t =3D U{};
}
func<type_1, type_2>();
This function - assuming a compiler that does no elision, or that elision=
=20
has been disabled - will always create the temporary then construct the=20
object with it under current rules. With proposed change, it will continue=
=20
to do that... except when T and U resolve to the same type. In that case,=
=20
the statement is interpreted as a direct default construction of "t".
But of course, who seriously turns off elision, or requires that it be=20
disabled? And if you really want that series of operations, relying on=20
compiler switches means your code is unportable anyway. You could get the=
=20
same behaviour, portably, by just writing it over two lines.
There are still some edge cases I'm not sure how to handle. For example,=20
how to handle the case in "XXX x =3D YYY{...};" where the two types differ=
=20
only in cv-qualification. Or referenceness. I'm inclined to say "ignore cv=
=20
differences ("x" will have the cv qualifiers of "XXX", not "YYY"), but=20
don't ignore referenceness (interpret that the same as today)".
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_165_1303164199.1441944131499
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Wednesday, 9 September 2015 22:53:52 UTC-4, David Kraus=
s wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: =
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div style=3D"word-wr=
ap:break-word">Elision hasn=E2=80=99t been mentioned yet :( .</div></blockq=
uote><div>=C2=A0<br>The first 3/4 of the original post was just a whirlwind=
rush through the rationale of why I'm proposing what I'm proposing=
, haphazardly glossing over numerous and sundry details that aren't rea=
lly relevant. To reiterate the reasoning:<br><ul><li>There are myriad ways =
to define new objects.</li><li>Every one of those ways has at least one fai=
l case or gotcha.</li><li>Most of the ways cannot be salvaged - the fail ca=
se or gotcha cannot be fixed without creating other headaches.</li><li>But =
there is one way that is almost perfect, and for which a fix is plausible: =
the form "<span style=3D"font-family: courier new,monospace;">XXX x =
=3D YYY{...};</span>", where "<span style=3D"font-family: courier=
new,monospace;">XXX</span>" and "<span style=3D"font-family: cou=
rier new,monospace;">YYY</span>" resolve to exactly the same type. (Yo=
u can replace the braces with parentheses, too.)</li><li>The only gotcha in=
that case is that it doesn't work for non-movable and non-copyable typ=
es (though it does work for non-movable/copyable and movable/non-copyable t=
ypes).</li><li>What makes this gotcha even more absurd is that, in reality,=
no move or copy ever happens, due to elision.</li><li>This elision, which =
changes the observable behaviour of the program, is allowed by the standard=
, but not required... and this is why that form doesn't work for non-mo=
vable/non-copyable types.</li><li>So what my proposal is, is make that elis=
ion "mandatory", in effect - or rather, reinterpret statements of=
the form "<span style=3D"font-family: courier new,monospace;">XXX x =
=3D YYY{...};</span>" to be a "definition statement", which =
is identical in meaning to "<span style=3D"font-family: courier new,mo=
nospace;">YYY x{...};</span>" (or you can substitute parentheses, and =
you won't get bitten by the MVP). In other words, making it a new form =
of direct construction expression.</li><li>What this proposal does is:</li>=
<ul><li>Gives us one perfect way to direct define/define new variables that=
works in all contexts, all the time, generic or not, no exceptions.</li><l=
i>With a syntax that is easy to understand, clear, familiar and consistent =
with other types of construction (such as copy/move/conversion construction=
"<span style=3D"font-family: courier new,monospace;">XXX x =3D val;</=
span>").</li><li>With all the flexibility you can possibly want (you c=
an use braces or parentheses, as you please, and they will select list cons=
tructors or not as per current rules).</li><li>Without breaking any current=
ly legal code.<br></li></ul></ul>Note that this has nothing to do with fact=
ory functions - whether for non-value types or not - and so is unrelated to=
the discussion going on elsewhere.<br><br></div><blockquote class=3D"gmail=
_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;p=
adding-left: 1ex;"><div style=3D"word-wrap:break-word">Writing random code =
from no semantic premises, and guessing at meaning from the perspective of =
a naive person, is not part of language design.<div><div><br></div><div>The=
solution to this problem is that newbies shouldn=E2=80=99t write non-value=
-semantic classes. Deleting the move constructor is a red flag, indicating =
that programming assistance is needed.</div><div><br></div><div>(Snip =E2=
=80=94 the newbie did not seek help. This seldom ends well in any language.=
)</div></div></div></blockquote><div><br>Most of my best students are those=
who took the initiative to figure things out in the language via experimen=
tation. When you can't do that - or worse, as in this situation, when e=
xperimentation leads you confidently to the wrong answer - that means the l=
anguage simply doesn't make sense. I don't think the correct answer=
to that dilemma is "you shouldn't experiment". The problem i=
s not the student, it's the language.<br><br>Nothing rules out consulti=
ng an expert, of course, but the point is that you have to know <i>when</i>=
to consult an expert, and what questions to ask. You can't simply walk=
up to a language expert and say "just tell me everything". All e=
xperts and help communities expect you to do your homework and come prepare=
d only with those questions you can't figure out on your own. (And in t=
his case, trying to figure it out on your own will lead you to the wrong an=
swer. Thus, we have a problem.)<br><br>Actually, making the language make m=
ore sense to beginners is my primary motivation for proposing this change (=
but also, easier generic programming). I would love to be able to tell the =
people I teach, on day 1 with no hemming or hawing or qualification: "=
This is how you create a new object in C++. Just do this. Auto, name, equal=
s, type, braces, semicolon. Done. Want to initialize with a specific value?=
Stick it in the braces. Yes, there are other ways that you'll certainl=
y see in other people's code, and in time - when we cover more topics -=
we'll talk about the various pros, cons, and gotchas. For now, just do=
this. It works." Then I can move on to teaching them actually useful =
things, and not have them come up to me a couple days later, "um, I tr=
ied to use this lock guard, and...".<br><br>Simple things should be si=
mple. There doesn't need to be a goblin lurking in every single corner =
of the language.<br>=C2=A0<br></div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><div style=3D"word-wrap:break-word">And BTW, I agree with Ville=E2=80=
=99s that your proposal is closely aligned with N4014. They both result fro=
m blaming the problems of non-value-semantic classes on the equals sign ins=
tead of the class. The equals sign is a safety mechanism to protect you fro=
m thorny types; getting rid of its significance will only open the gates to=
more nastiness.</div></blockquote><div><br>Okay, I think I'm cluing in=
to what you and Ville are saying. When referring to the relationship to N4=
014, you are not actually referring to the actual content of the paper (or =
the note on why it was rejected), but rather to what I assume is a discussi=
on that went on behind the scenes. That discussion was not just on the spec=
ific issue (of explicitness), but a broader discussion about protecting the=
purity of separation between value types and non-value types.<br><br>And I=
gather what you're saying is that you want the equals sign to be the l=
ine of separation between value types and non-value types - that is, when y=
ou're using an equal sign, you must be working with a value type.<br><b=
r>Does that correctly summarize what you and Ville are getting at?<br><br>A=
ssuming so, I have to disagree with the reasoning. I don't disagree wit=
h maintaining a bright line of separation between value types and non-value=
types (let's just go with VTs and NVTs) - what I disagree with is that=
the equal sign is worth defending for this cause. I would say that battle =
is over, and purity lost. Here's why:<br><div class=3D"prettyprint" sty=
le=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187=
); border-style: solid; border-width: 1px; word-wrap: break-word;"><code cl=
ass=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">atomic</span><span style=3D"color: #080;" =
class=3D"styled-by-prettify"><int></span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"> x </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">{};</span></div></code></div><br>That works, but this doesn't:<=
br><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250)=
; border-color: rgb(187, 187, 187); border-style: solid; border-width: 1px;=
word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subprett=
yprint"><span style=3D"color: #000;" class=3D"styled-by-prettify">atomic</s=
pan><span style=3D"color: #080;" class=3D"styled-by-prettify"><int></=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> x </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> atomic</span><span style=
=3D"color: #080;" class=3D"styled-by-prettify"><int></span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">{};</span></div></code></di=
v><br>So logically that means that the first statement is not really constr=
ucting an atomic on the right - it's (in essence) assigning (which is r=
eally a conversion construction) the (empty) list object on the right to th=
e atomic on the left.<br><br>But if that's so, then why doesn't it =
work with types with an explicit default constructor?<br><br>The fact that =
it fails when the constructor is explicit implies that there must be (impli=
citly) an <span style=3D"font-family: courier new,monospace;">atomic<int=
></span> construction going on on the right. I mean, you can't sanel=
y argue that whatever is being constructed on the left isn't explicitly=
an <span style=3D"font-family: courier new,monospace;">atomic<int></=
span>, right?<br><br>Yet if that is what is happening, then why does the se=
cond form fail? Isn't it doing exactly the same thing. Only... *wince*.=
... explicitly?<br><br>So the equal sign is already in a dire mess when it c=
omes to drawing a bright line between VTs and NVTs. Digging in and defendin=
g it for that purpose seems quixotic.<br><br>I also don't see any point=
in blaming NVTs for the mess, and saying "types should always be VTs.=
... except when they can't possibly, and in that case, damn them to hell=
". Or rather, "yes, this is a mess, but it's only a mess when=
you use NVTs, so don't use them... unless you really, really have to, =
and if you have to, well, just suck up and accept the pain" (which rem=
inds me of that old joke about the doctor and "it hurts when I do this=
"). I do agree that you should strongly prefer value semantics for you=
r types, but the reality is that there are types for which that simply does=
n't work, and those types aren't exactly rare or obscure. (You can =
make a valid argument against using mutexes and atomics all over the place =
- and maybe even locks - because there are better options for concurrency a=
nd parallelism, but what about scope guard objects? Like things that manage=
commit-or-rollback for transaction-like operations.) Creating one universa=
l way to create objects really doesn't open the floodgates to making NV=
Ts generally easy to use. After all, if your coding standard specified alwa=
ys using non-auto copy-/direct-list-initialization, that ship's already=
sailed anyway.<br><br>What I'm proposing is to change the way you thin=
k about the equal sign in expressions of the form "<span style=3D"font=
-family: courier new,monospace;">XXX x =3D YYY{...};</span>". Don'=
t think of it as an assignment operation (which, frankly, it already isn=
9;t - it doesn't call any assignment operation, it does a (copy/move) c=
onstruction). Think of it not as a mathematical "equality" (which=
it already isn't really) but rather as a "definition". Menta=
lly replace it not with "takes the value of", but rather "is=
".<br><br>And there is precedence for this in C++.<br><div class=3D"pr=
ettyprint" style=3D"background-color: rgb(250, 250, 250); border-color: rgb=
(187, 187, 187); border-style: solid; border-width: 1px; word-wrap: break-w=
ord;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=
=3D"color: #800;" class=3D"styled-by-prettify">// This is not an operation =
on values</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">using</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> type </span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> other_type</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color=
: #800;" class=3D"styled-by-prettify">// Neither is this</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">namespace</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> ns </span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> verbose</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify">name</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y">space</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;<=
/span></div></code></div><br>In other words, in the context of statements o=
f the form "<span style=3D"font-family: courier new,monospace;">XXX x =
=3D YYY{...};</span>", where "<span style=3D"font-family: courier=
new,monospace;">XXX</span>" and "<span style=3D"font-family: cou=
rier new,monospace;">YYY</span>" resolve to exactly the same type, the=
equals doesn't describe a transmission of value, but rather an alias. =
You can view it as defining a label "<span style=3D"font-family: couri=
er new,monospace;">x</span>", which is interpreted as a "<span st=
yle=3D"font-family: courier new,monospace;">YYY</span>" object (rememb=
er, "<span style=3D"font-family: courier new,monospace;">XXX</span>&qu=
ot; resolves to the exact same type, but "<span style=3D"font-family: =
courier new,monospace;">XXX</span>" might be "<span style=3D"font=
-family: courier new,monospace;">auto</span>" whereas "<span styl=
e=3D"font-family: courier new,monospace;">YYY</span>" cannot be), that=
is bound to the temporary that is created on the right, and the lifetime o=
f the temporary is extended for the lifetime of the label "<span style=
=3D"font-family: courier new,monospace;">x</span>".<br><br>And this fo=
rm of variable definition is not revolutionary. Many languages have similar=
constructs<br><div class=3D"prettyprint" style=3D"background-color: rgb(25=
0, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; border=
-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=
=3D"subprettyprint"><span style=3D"color: #800;" class=3D"styled-by-prettif=
y">// Perl</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">my</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> $x </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> initializer</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br><br></span><span style=3D"colo=
r: #800;" class=3D"styled-by-prettify">// OCaml, Rust</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br>let x </span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> initializer</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"><br><br></span><span style=3D"color: #800;" cl=
ass=3D"styled-by-prettify">// JavaScript, Swift</span><span style=3D"color:=
#000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">var</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> x </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> initializer</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><br><br></span><span style=3D"color: #800;" class=3D"styled-by-prettify"=
>// C++, conceptually</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
x </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> initializer</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span></div=
></code></div><br>Obviously the circumstances are very different in those o=
ther languages, and I'm not suggesting the semantics be duplicated in C=
++. I'm just saying the form is familiar. It just "looks like"=
; you're creating the object on the left, and describing an alias to it=
on the right.<br><br>Another side effect of this change would be creating =
a kind of beautiful, simplistic consistency in the language. Here is what i=
t would look like if you are using explicit types (no "<span style=3D"=
font-family: courier new,monospace;">auto</span>"):<br><div class=3D"p=
rettyprint" style=3D"background-color: rgb(250, 250, 250); border-color: rg=
b(187, 187, 187); border-style: solid; border-width: 1px; word-wrap: break-=
word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">type x </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> type</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">{};</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> =C2=A0</span><span style=3D"color: #800;" clas=
s=3D"styled-by-prettify">// (direct) default construction</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>type x </span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> type</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">();</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> =C2=A0</span><span style=3D"color: #800;" cla=
ss=3D"styled-by-prettify">// same</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span><span style=3D"color: #800;" class=3D"st=
yled-by-prettify">// Both of the above work for *all* types that have defau=
lt constructors,</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br></span><span style=3D"color: #800;" class=3D"styled-by-prettify">=
// regardless of whether it's explicit or not, regardless of whether th=
e type</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
</span><span style=3D"color: #800;" class=3D"styled-by-prettify">// is mova=
ble and/or copyable. It Just Works(tm).</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"><br><br>type x </span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> type</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">{...};</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> =C2=A0</span><span style=3D"color: #800;" class=3D"sty=
led-by-prettify">// (explicit, direct) list initialization</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br>type x </span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> type</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">(...);</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> =C2=A0</span><span style=3D"color: #800;"=
class=3D"styled-by-prettify">// (explicit, direct) non-list initialization=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span=
><span style=3D"color: #800;" class=3D"styled-by-prettify">// Both of the a=
bove work for *all* types that have the constructor with the</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D=
"color: #800;" class=3D"styled-by-prettify">// given signature, regardless =
of whether it's explicit or not, regardless of</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #8=
00;" class=3D"styled-by-prettify">// whether the type is movable and/or cop=
yable. As with today, an initializer</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br></span><span style=3D"color: #800;" class=3D"=
styled-by-prettify">// list constructor gets priority in the first case, an=
d a non-initializer-list</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"><br></span><span style=3D"color: #800;" class=3D"styled-by-pr=
ettify">// constructor gets priority in the second case. It Just Works(tm).=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br>ty=
pe x </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> lvalue</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color: #800;" class=3D"sty=
led-by-prettify">// copy construction (presumably)</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br>type x </span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> rvalue</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</=
span><span style=3D"color: #800;" class=3D"styled-by-prettify">// move cons=
truction (presumably)</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br>type x </span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">:=
:</span><span style=3D"color: #000;" class=3D"styled-by-prettify">move</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">lvalue</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> =C2=A0 </span><span style=3D"color:=
#800;" class=3D"styled-by-prettify">// move construction (presumably)</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>type x </sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> factory_function</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">();</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0</span><span s=
tyle=3D"color: #800;" class=3D"styled-by-prettify">// move construction (pr=
esumably)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br></span><span style=3D"color: #800;" class=3D"styled-by-prettify">// The =
semantics of the above don't change - they only work for types that</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><sp=
an style=3D"color: #800;" class=3D"styled-by-prettify">// allow copy/move c=
onstruction. These all Just Work(tm) for value types.</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br><br>type x </span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #066=
;" class=3D"styled-by-prettify">0</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> =C2=A0 =C2=A0</span><span style=3D"color: #800;" class=3D"s=
tyled-by-prettify">// int</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>type x </span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
{</span><span style=3D"color: #066;" class=3D"styled-by-prettify">0</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">};</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0</span><span style=
=3D"color: #800;" class=3D"styled-by-prettify">// int</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color:=
#800;" class=3D"styled-by-prettify">// The semantics of the above don'=
t change.</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br><br></span><span style=3D"color: #800;" class=3D"styled-by-prettify">// =
The type names don't need to be identical, they just need to resolve to=
the</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></=
span><span style=3D"color: #800;" class=3D"styled-by-prettify">// same type=
..</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">using</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">alias</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> type</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">alias</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> x </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> type</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">{};</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0</span><span style=
=3D"color: #800;" class=3D"styled-by-prettify">// (direct) default construc=
tion</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></=
span><span style=3D"color: #008;" class=3D"styled-by-prettify">alias</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> x </span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> type</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">();</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> =C2=A0</span><span style=3D"color: #800;" =
class=3D"styled-by-prettify">// same</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">alias</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> x </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> type</span><span style=3D"color: #660;" class=3D"styled-by-prettify">{...=
};</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0<=
/span><span style=3D"color: #800;" class=3D"styled-by-prettify">// (explici=
t, direct) list initialization</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"styled=
-by-prettify">alias</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> x </span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> type=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(...);</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0</span>=
<span style=3D"color: #800;" class=3D"styled-by-prettify">// (explicit, dir=
ect) non-list initialization</span></div></code></div><br>Things get even s=
impler, and more elegant, when you use "<span style=3D"font-family: co=
urier new,monospace;">auto</span>":<br><div class=3D"prettyprint" styl=
e=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187)=
; border-style: solid; border-width: 1px; word-wrap: break-word;"><code cla=
ss=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008=
;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> x </span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> type</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">{};</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
=C2=A0</span><span style=3D"color: #800;" class=3D"styled-by-prettify">// =
(direct) default construction</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-=
by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> x </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> type</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">();</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0</span><span=
style=3D"color: #800;" class=3D"styled-by-prettify">// same</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D=
"color: #800;" class=3D"styled-by-prettify">// Both of the above work for *=
all* types that have default constructors,</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #800;" cla=
ss=3D"styled-by-prettify">// regardless of whether it's explicit or not=
, regardless of whether the type</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span><span style=3D"color: #800;" class=3D"st=
yled-by-prettify">// is movable and/or copyable. It Just Works(tm).</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> x </span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> type</span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">{...};</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> =C2=A0</span><span style=3D"color: #800;" class=
=3D"styled-by-prettify">// (explicit, direct) list initialization</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> x </span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> type</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(...);</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> =C2=A0</span><span style=3D"color: #800;" class=3D"sty=
led-by-prettify">// (explicit, direct) non-list initialization</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=
=3D"color: #800;" class=3D"styled-by-prettify">// Both of the above work fo=
r *all* types that have the constructor with the</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #800=
;" class=3D"styled-by-prettify">// given signature, regardless of whether i=
t's explicit or not, regardless of</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br></span><span style=3D"color: #800;" class=
=3D"styled-by-prettify">// whether the type is movable and/or copyable. As =
with today, an initializer</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br></span><span style=3D"color: #800;" class=3D"styled-by-=
prettify">// list constructor gets priority in the first case, and a non-in=
itializer-list</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"><br></span><span style=3D"color: #800;" class=3D"styled-by-prettify">//=
constructor gets priority in the second case. It Just Works(tm).</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><span=
style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> x </span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> lvalue</span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</spa=
n><span style=3D"color: #800;" class=3D"styled-by-prettify">// copy constru=
ction (presumably)</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify=
">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> x <=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> rvalue</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0=
=C2=A0 =C2=A0 =C2=A0</span><span style=3D"color: #800;" class=3D"styled-by=
-prettify">// move construction (presumably)</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> x </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> std</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">move=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify">lvalue</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> =C2=A0 </span><span style=3D"c=
olor: #800;" class=3D"styled-by-prettify">// move construction (presumably)=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"> x </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> factory_function</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">();</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> =C2=A0</span><span style=3D"color:=
#800;" class=3D"styled-by-prettify">// move construction (presumably)</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><spa=
n style=3D"color: #800;" class=3D"styled-by-prettify">// The semantics of t=
he above don't change - they only work for types that</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"co=
lor: #800;" class=3D"styled-by-prettify">// allow copy/move construction. T=
hese all Just Work(tm) for value types.</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"><br><br></span><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> x </span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #066;" class=3D"styled-by-prettify">0<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0</span=
><span style=3D"color: #800;" class=3D"styled-by-prettify">// int</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> x </span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">{</span><span style=3D"color: #066;" class=3D"styled-by=
-prettify">0</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">};</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=
=A0</span><span style=3D"color: #800;" class=3D"styled-by-prettify">// std:=
:initializer_list<int> (with one element, that is 0)</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color: #800;" class=
=3D"styled-by-prettify">// which is different from using explicit type (but=
still clear)</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><br></span><span style=3D"color: #800;" class=3D"styled-by-prettify">// =
The semantics of the above don't change.</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br><br></span><span style=3D"color: #800=
;" class=3D"styled-by-prettify">// No issues with type aliasing</span></div=
></code></div><br>I can only think of two potential gotchas, but they'r=
e both rather esoteric cases.<br><br>Case 1 is code that relies on the curr=
ent behaviour:<br><div class=3D"prettyprint" style=3D"background-color: rgb=
(250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; bor=
der-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div cl=
ass=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">template</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify"><<=
/span><span style=3D"color: #008;" class=3D"styled-by-prettify">typename</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> T</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">></span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> func</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">()</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br>=C2=A0 </span><span style=3D"color: #800;" class=3D"styled-by-=
prettify">// I expect this template function to only be instantiated for ty=
pes that are</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br>=C2=A0 </span><span style=3D"color: #800;" class=3D"styled-by-prettif=
y">// movable and/or copyable, and rather than expressing this via traits o=
r</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=
=A0 </span><span style=3D"color: #800;" class=3D"styled-by-prettify">// con=
cepts, I'm relying on the current interpretation of the following lines=
:</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=
=A0 T t1 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> T</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">{};</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> t1 </span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> T</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">{};</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">}</span></div></code></div><br>This function fails to compile=
today for non-movable/non-copyable types, but will with my proposed change=
..<br><br>However, I have never seen any code that relied on that, and I wou=
ld argue any code that did was already a maintenance headache.<br><br>Case =
2 is code that gets bitten by type aliasing:<br><div class=3D"prettyprint" =
style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, =
187); border-style: solid; border-width: 1px; word-wrap: break-word;"><code=
class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: =
#800;" class=3D"styled-by-prettify">// assuming type_1 is non-copyable and =
non-movable</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">using=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> type_2 </=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> type_1</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"><br><br></span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">template</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;=
" class=3D"styled-by-prettify"><</span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">typename</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> T</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">ty=
pename</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> U</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">></span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> func</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">()</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br>=C2=A0 </span><span style=3D"color: #800;" class=3D"=
styled-by-prettify">// I expect this template function to do a default cons=
truction of a temporary</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"><br>=C2=A0 </span><span style=3D"color: #800;" class=3D"styled=
-by-prettify">// U object, then a conversion construction of a T using that=
temporary.</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br>=C2=A0 </span><span style=3D"color: #800;" class=3D"styled-by-prettify=
">// In fact, I *INSIST* on this behaviour, and even use a special compiler=
, or</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
=C2=A0 </span><span style=3D"color: #800;" class=3D"styled-by-prettify">// =
compiler switches, to make it happen.</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"><br>=C2=A0 T t </span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> U</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">{};</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><=
br>func</span><span style=3D"color: #660;" class=3D"styled-by-prettify"><=
;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">type_1</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"> type_2</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">>();</span></div></cod=
e></div><br>This function - assuming a compiler that does no elision, or th=
at elision has been disabled - will always create the temporary then constr=
uct the object with it under current rules. With proposed change, it will c=
ontinue to do that... except when <span style=3D"font-family: courier new,m=
onospace;">T</span> and <span style=3D"font-family: courier new,monospace;"=
>U</span> resolve to the same type. In that case, the statement is interpre=
ted as a direct default construction of "<span style=3D"font-family: c=
ourier new,monospace;">t</span>".<br><br>But of course, who seriously =
turns off elision, or requires that it be disabled? And if you really want =
that series of operations, relying on compiler switches means your code is =
unportable anyway. You could get the same behaviour, portably, by just writ=
ing it over two lines.<br><br>There are still some edge cases I'm not s=
ure how to handle. For example, how to handle the case in "<span style=
=3D"font-family: courier new,monospace;">XXX x =3D YYY{...};</span>" w=
here the two types differ only in cv-qualification. Or referenceness. I'=
;m inclined to say "ignore cv differences ("<span style=3D"font-f=
amily: courier new,monospace;">x</span>" will have the cv qualifiers o=
f "<span style=3D"font-family: courier new,monospace;">XXX</span>"=
;, not "<span style=3D"font-family: courier new,monospace;">YYY</span>=
"), but don't ignore referenceness (interpret that the same as tod=
ay)".</div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_165_1303164199.1441944131499--
------=_Part_164_706540651.1441944131497--
.
Author: Tomasz <tomaszkam@gmail.com>
Date: Thu, 10 Sep 2015 21:43:49 -0700 (PDT)
Raw View
------=_Part_199_120594849.1441946629506
Content-Type: multipart/alternative;
boundary="----=_Part_200_1076249581.1441946629507"
------=_Part_200_1076249581.1441946629507
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
W dniu czwartek, 10 wrze=C5=9Bnia 2015 01:27:18 UTC+2 u=C5=BCytkownik Mark =
A. Gibbs=20
napisa=C5=82:
>
>
> But if you don't have a value, or if you do but you want to be explicit=
=20
> about the type, you can use:
> auto v =3D type{val}; // or any other constructor arguments, including n=
one
>
>
I feel sad when a people want to eliminate all the work that was done on=20
checking the units and the ratios on compile time, just to force the use of=
=20
shinny new auto. Please assume that I want to receive a duration in=20
seconds, and compare the results of:
std::chrono::seconds s =3D get_timeout();
auto s =3D std::chrono::seconds{s};
std::chrono::seconds s{get_timeout()};
To help out a bit, please consider following declarations:
int get_timeout(); //return number of seconds
std::chrono::seconds get_timeout();
And how the program will behave if one is replaced with another, or the=20
unit is changed.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_200_1076249581.1441946629507
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>W dniu czwartek, 10 wrze=C5=9Bnia 2015 01:27:18 UT=
C+2 u=C5=BCytkownik Mark A. Gibbs napisa=C5=82:<blockquote class=3D"gmail_q=
uote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;pad=
ding-left: 1ex;"><div dir=3D"ltr"><br>But if you don't have a value, or=
if you do but you want to be explicit about the type, you can use:<br><div=
style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);b=
order-style:solid;border-width:1px;word-wrap:break-word"><code><div><span s=
tyle=3D"color:#008">auto</span><span style=3D"color:#000"> v </span><span s=
tyle=3D"color:#660">=3D</span><span style=3D"color:#000"> type</span><span =
style=3D"color:#660">{</span><span style=3D"color:#000">val</span><span sty=
le=3D"color:#660">};</span><span style=3D"color:#000"> =C2=A0</span><span s=
tyle=3D"color:#800">// or any other constructor arguments, including none</=
span></div></code></div><br></div></blockquote><div><br>I feel sad when a p=
eople want to eliminate all the work that was done on checking the units an=
d the ratios on compile time, just to force the use of shinny new auto. Ple=
ase assume that I want to receive a duration in seconds, and compare the re=
sults of:<br>std::chrono::seconds s =3D get_timeout();<br>auto s =3D std::c=
hrono::seconds{s};<br>std::chrono::seconds s{get_timeout()};<br><br>To help=
out a bit, please consider following declarations:<br>int get_timeout(); /=
/return number of seconds<br>std::chrono::seconds get_timeout();<br>And how=
the program will behave if one is replaced with another, or the unit is ch=
anged.<br><br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_200_1076249581.1441946629507--
------=_Part_199_120594849.1441946629506--
.
Author: "Mark A. Gibbs" <indi.in.the.wired@gmail.com>
Date: Thu, 10 Sep 2015 23:12:14 -0700 (PDT)
Raw View
------=_Part_184_1537413759.1441951934545
Content-Type: multipart/alternative;
boundary="----=_Part_185_1530623330.1441951934545"
------=_Part_185_1530623330.1441951934545
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Friday, 11 September 2015 00:43:49 UTC-4, Tomasz wrote:
>
>
>
> W dniu czwartek, 10 wrze=C5=9Bnia 2015 01:27:18 UTC+2 u=C5=BCytkownik Mar=
k A. Gibbs=20
> napisa=C5=82:
>>
>>
>> But if you don't have a value, or if you do but you want to be explicit=
=20
>> about the type, you can use:
>> auto v =3D type{val}; // or any other constructor arguments, including=
=20
>> none
>>
>>
> I feel sad when a people want to eliminate all the work that was done on=
=20
> checking the units and the ratios on compile time, just to force the use =
of=20
> shinny new auto. Please assume that I want to receive a duration in=20
> seconds, and compare the results of:
> std::chrono::seconds s =3D get_timeout();
> auto s =3D std::chrono::seconds{s};
> std::chrono::seconds s{get_timeout()};
>
> To help out a bit, please consider following declarations:
> int get_timeout(); //return number of seconds
> std::chrono::seconds get_timeout();
> And how the program will behave if one is replaced with another, or the=
=20
> unit is changed.
>
=20
Could you please explain exactly what behaviour you think would be=20
surprising or problematic, with respect to the proposal in this topic?
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_185_1530623330.1441951934545
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Friday, 11 September 2015 00:43:49 UTC-4, Tomasz wrote:<blockquote clas=
s=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #c=
cc solid;padding-left: 1ex;"><div dir=3D"ltr"><br><br>W dniu czwartek, 10 w=
rze=C5=9Bnia 2015 01:27:18 UTC+2 u=C5=BCytkownik Mark A. Gibbs napisa=C5=82=
:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bord=
er-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br>But if you do=
n't have a value, or if you do but you want to be explicit about the ty=
pe, you can use:<br><div style=3D"background-color:rgb(250,250,250);border-=
color:rgb(187,187,187);border-style:solid;border-width:1px;word-wrap:break-=
word"><code><div><span style=3D"color:#008">auto</span><span style=3D"color=
:#000"> v </span><span style=3D"color:#660">=3D</span><span style=3D"color:=
#000"> type</span><span style=3D"color:#660">{</span><span style=3D"color:#=
000">val</span><span style=3D"color:#660">};</span><span style=3D"color:#00=
0"> =C2=A0</span><span style=3D"color:#800">// or any other constructor arg=
uments, including none</span></div></code></div><br></div></blockquote><div=
><br>I feel sad when a people want to eliminate all the work that was done =
on checking the units and the ratios on compile time, just to force the use=
of shinny new auto. Please assume that I want to receive a duration in sec=
onds, and compare the results of:<br>std::chrono::seconds s =3D get_timeout=
();<br>auto s =3D std::chrono::seconds{s};<br>std::chrono::seconds s{get_ti=
meout()};<br><br>To help out a bit, please consider following declarations:=
<br>int get_timeout(); //return number of seconds<br>std::chrono::seconds g=
et_timeout();<br>And how the program will behave if one is replaced with an=
other, or the unit is changed.<br></div></div></blockquote><div>=C2=A0<br>C=
ould you please explain exactly what behaviour you think would be surprisin=
g or problematic, with respect to the proposal in this topic?<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_185_1530623330.1441951934545--
------=_Part_184_1537413759.1441951934545--
.
Author: Tomasz <tomaszkam@gmail.com>
Date: Fri, 11 Sep 2015 01:00:52 -0700 (PDT)
Raw View
------=_Part_116_498682170.1441958452926
Content-Type: multipart/alternative;
boundary="----=_Part_117_1674675022.1441958452931"
------=_Part_117_1674675022.1441958452931
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
W dniu pi=C4=85tek, 11 wrze=C5=9Bnia 2015 08:12:14 UTC+2 u=C5=BCytkownik Ma=
rk A. Gibbs=20
napisa=C5=82:
>
> On Friday, 11 September 2015 00:43:49 UTC-4, Tomasz wrote:
>>
>>
>>
>> W dniu czwartek, 10 wrze=C5=9Bnia 2015 01:27:18 UTC+2 u=C5=BCytkownik Ma=
rk A. Gibbs=20
>> napisa=C5=82:
>>>
>>>
>>> But if you don't have a value, or if you do but you want to be explicit=
=20
>>> about the type, you can use:
>>> auto v =3D type{val}; // or any other constructor arguments, including=
=20
>>> none
>>>
>>>
>> I feel sad when a people want to eliminate all the work that was done on=
=20
>> checking the units and the ratios on compile time, just to force the use=
of=20
>> shinny new auto. Please assume that I want to receive a duration in=20
>> seconds, and compare the results of:
>> std::chrono::seconds s =3D get_timeout();
>> auto s =3D std::chrono::seconds{s};
>> std::chrono::seconds s{get_timeout()};
>>
>> To help out a bit, please consider following declarations:
>> int get_timeout(); //return number of seconds
>> std::chrono::seconds get_timeout();
>> And how the program will behave if one is replaced with another, or the=
=20
>> unit is changed.
>>
> =20
> Could you please explain exactly what behaviour you think would be=20
> surprising or problematic, with respect to the proposal in this topic?
>
The motivation behind proposed change is to allow "one proper"=20
initialization syntax for the case, when the user want to commit to a=20
specific type:
auto x =3D type{expr};
The example when the syntax are discussed usually present the situation=20
when the expression has type visible at the point of variable declaration.=
=20
Like constant in the blog example, but to see the difference and value of=
=20
having direct and copy intialization we need to discuss a example when type=
=20
of expr is not know or may be changed in the future - the cases when the=20
variable is initialized from a return of the function foo().
The difference between direct and non-direct initialization give us two=20
options:
Type x =3D foo(); //This will compile only if there is implicit conversion=
=20
between result of foo() and Type
Type x(foo()); //Will compile when there is explicit conversion from result=
=20
of foo() and Type
This is just other side of the coin, and allow to use the same conversion=
=20
to pass result from callee to caller, as in passing argument form caller to=
=20
callee.
Then there is a whole paradigm of having "meaningful types" that uses type=
=20
checking do differentiate between number of seconds and milliseconds or=20
between the weight of thing in newtons and mass in grams. Such "opaque"=20
class usually marks constructors that add semantics information (from bare=
=20
number to seconds) as explicit, so following will work:
std::chrono::seconds s =3D get_timeout();=20
Only if the get_timeout() will return a appropriate duration time. I am=20
using the compiler to check if the conversion is safe and I actually=20
getting the right number. But following:
std::chrono::seconds s(get_timeout());
Will work even if the get_timeout() is returning bare number. Now I am=20
taking resposibility for making sure that the number is actually number of=
=20
seconds not milliseconds.
Finally, returning to original topic. In case if we stick to use of the use=
=20
of ETTI only:
auto s =3D std::chrono::seconds(get_timeout());
The programmer has no longer way to express the fact that he wants only=20
implicit conversion to be invoked. This basically eliminates all the gain=
=20
that was achieved by meaningful types, but introducing unintended=20
conversion. I do think that teaching the initialization syntax that will=20
eliminate gains for unit/ratio classes is good direction.
Ironically the poeple that are promoting auto everywhere syntax are given=
=20
argument about lack of unintended conversion as argument for using it.=20
While use ETTI (auto x =3D type(expr)) acutally introduce possibility of mo=
re=20
bogus one. Just think of the Herb Sutter example:
auto x =3D unique_ptr<Base>{createDerived()};
It is working correctly in case when createDerived() is retruning=20
unique_ptr<Derived>. But what if it will start to return raw pointer to=20
class to object that has lifetime handled eslewhere? The syntax:
unique_ptr<Base> x =3D createDerived();
Will catch such change at compile time.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_117_1674675022.1441958452931
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<br><br>W dniu pi=C4=85tek, 11 wrze=C5=9Bnia 2015 08:12:14 UTC+2 u=C5=BCytk=
ownik Mark A. Gibbs napisa=C5=82:<blockquote class=3D"gmail_quote" style=3D=
"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex=
;">On Friday, 11 September 2015 00:43:49 UTC-4, Tomasz wrote:<blockquote c=
lass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #c=
cc solid;padding-left:1ex"><div dir=3D"ltr"><br><br>W dniu czwartek, 10 wrz=
e=C5=9Bnia 2015 01:27:18 UTC+2 u=C5=BCytkownik Mark A. Gibbs napisa=C5=82:<=
blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border=
-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br>But if you don&=
#39;t have a value, or if you do but you want to be explicit about the type=
, you can use:<br><div style=3D"background-color:rgb(250,250,250);border-co=
lor:rgb(187,187,187);border-style:solid;border-width:1px;word-wrap:break-wo=
rd"><code><div><span style=3D"color:#008">auto</span><span style=3D"color:#=
000"> v </span><span style=3D"color:#660">=3D</span><span style=3D"color:#0=
00"> type</span><span style=3D"color:#660">{</span><span style=3D"color:#00=
0">val</span><span style=3D"color:#660">};</span><span style=3D"color:#000"=
> =C2=A0</span><span style=3D"color:#800">// or any other constructor argum=
ents, including none</span></div></code></div><br></div></blockquote><div><=
br>I feel sad when a people want to eliminate all the work that was done on=
checking the units and the ratios on compile time, just to force the use o=
f shinny new auto. Please assume that I want to receive a duration in secon=
ds, and compare the results of:<br>std::chrono::seconds s =3D get_timeout()=
;<br>auto s =3D std::chrono::seconds{s};<br>std::chrono::seconds s{get_time=
out()};<br><br>To help out a bit, please consider following declarations:<b=
r>int get_timeout(); //return number of seconds<br>std::chrono::seconds get=
_timeout();<br>And how the program will behave if one is replaced with anot=
her, or the unit is changed.<br></div></div></blockquote><div>=C2=A0<br>Cou=
ld you please explain exactly what behaviour you think would be surprising =
or problematic, with respect to the proposal in this topic?<br></div></bloc=
kquote><div><br>The motivation behind proposed change is to allow "one=
proper" initialization syntax for the case, when the user want to com=
mit to a specific type:<br>auto x =3D type{expr};<br>The example when the s=
yntax are discussed usually present the situation when the expression has t=
ype visible at the point of variable declaration. Like constant in the blog=
example, but to see the difference and value of having direct and copy int=
ialization we need to discuss a example when type of expr is not know or ma=
y be changed in the future - the cases when the variable is initialized fro=
m a return of the function foo().<br><br>The difference between direct and =
non-direct initialization give us two options:<br>Type x =3D foo();=C2=A0 /=
/This will compile only if there is implicit conversion between result of f=
oo() and Type<br>Type x(foo()); //Will compile when there is explicit conve=
rsion from result of foo() and Type<br>This is just other side of the coin,=
and allow to use the same conversion to pass result from callee to caller,=
as in passing argument form caller to callee.<br><br>Then there is a whole=
paradigm of having "meaningful types" that uses type checking do=
differentiate between number of seconds and milliseconds or between the we=
ight of thing in newtons and mass in grams. Such "opaque" class u=
sually marks constructors that add semantics information (from bare number =
to seconds) as explicit, so following will work:<br>std::chrono::seconds s =
=3D get_timeout(); <br>Only if the get_timeout() will return a appropriate =
duration time. I am using the compiler to check if the conversion is safe a=
nd I actually getting the right number. But following:<br>std::chrono::seco=
nds s(get_timeout());<br>Will work even if the get_timeout() is returning b=
are number. Now I am taking resposibility for making sure that the number i=
s actually number of seconds not milliseconds.<br><br>Finally, returning to=
original topic. In case if we stick to use of the use of ETTI only:<br>aut=
o s =3D std::chrono::seconds(get_timeout());<br>The programmer has no longe=
r way to express the fact that he wants only implicit conversion to be invo=
ked. This basically eliminates all the gain that was achieved by meaningful=
types, but introducing unintended conversion. I do think that teaching the=
initialization syntax that will eliminate gains for unit/ratio classes is =
good direction.<br><br>Ironically the poeple that are promoting auto everyw=
here syntax are given argument about lack of unintended conversion as argum=
ent for using it. While use ETTI (auto x =3D type(expr)) acutally introduce=
possibility of more bogus one. Just think of the Herb Sutter example:<br>a=
uto x =3D unique_ptr<Base>{createDerived()};<br>It is working correct=
ly in case when createDerived() is retruning unique_ptr<Derived>. But=
what if it will start to return raw pointer to class to object that has li=
fetime handled eslewhere? The syntax:<br>unique_ptr<Base> x =3D creat=
eDerived();<br>Will catch such change at compile time.<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_117_1674675022.1441958452931--
------=_Part_116_498682170.1441958452926--
.
Author: David Krauss <potswa@gmail.com>
Date: Fri, 11 Sep 2015 16:11:36 +0800
Raw View
--Apple-Mail=_09CFDD7F-7526-48BB-B89E-27A834E77CC6
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
> On 2015=E2=80=9309=E2=80=9311, at 12:02 PM, Mark A. Gibbs <indi.in.the.wi=
red@gmail.com <mailto:indi.in.the.wired@gmail.com>> wrote:
>=20
> Most of my best students are those who took the initiative to figure thin=
gs out in the language via experimentation. When you can't do that - or wor=
se, as in this situation, when experimentation leads you confidently to the=
wrong answer - that means the language simply doesn't make sense. I don't =
think the correct answer to that dilemma is "you shouldn't experiment". The=
problem is not the student, it's the language.
I didn=E2=80=99t say not to experiment, I said that you get into trouble wh=
en you lose value semantics. The problem with the example is that its =E2=
=80=9Cexperiment=E2=80=9D just seems to be a random jumble of keywords, and=
then you say that the result is surprising. An experiment is something tha=
t tests a hypothesis, and the example never said what the student was after=
..
> Nothing rules out consulting an expert, of course, but the point is that =
you have to know when to consult an expert, and what questions to ask. You =
can't simply walk up to a language expert and say "just tell me everything"=
.. All experts and help communities expect you to do your homework and come =
prepared only with those questions you can't figure out on your own. (And i=
n this case, trying to figure it out on your own will lead you to the wrong=
answer. Thus, we have a problem.)
In this case, the question would be, =E2=80=9Cwhy doesn=E2=80=99t the equal=
s sign work=E2=80=9D? And the answer would be, =E2=80=9Cthe right-hand side=
doesn=E2=80=99t behave as a value.=E2=80=9D
> Actually, making the language make more sense to beginners is my primary =
motivation for proposing this change (but also, easier generic programming)=
..
The flip side of regular syntax with loose semantic constraints is getting =
unexpected meaning from templates. Some things aren=E2=80=99t supposed to c=
ompile.
> I would love to be able to tell the people I teach, on day 1 with no hemm=
ing or hawing or qualification: "This is how you create a new object in C++=
.. Just do this. Auto, name, equals, type, braces, semicolon. Done. Want to =
initialize with a specific value? Stick it in the braces. Yes, there are ot=
her ways that you'll certainly see in other people's code, and in time - wh=
en we cover more topics - we'll talk about the various pros, cons, and gotc=
has. For now, just do this. It works." Then I can move on to teaching them =
actually useful things, and not have them come up to me a couple days later=
, "um, I tried to use this lock guard, and=E2=80=A6".
There=E2=80=99s a language for that: Java. (Except, scalars in Java are new=
objects without using the new keyword.)
The extra bits of C++ are useful to make it a richer language. We can=E2=80=
=99t just sweep them under the rug. You can use AAA as far as value semanti=
cs go, but that won=E2=80=99t get you a lock guard.
> Simple things should be simple. There doesn't need to be a goblin lurking=
in every single corner of the language.
> =20
> And BTW, I agree with Ville=E2=80=99s that your proposal is closely align=
ed with N4014. They both result from blaming the problems of non-value-sema=
ntic classes on the equals sign instead of the class. The equals sign is a =
safety mechanism to protect you from thorny types; getting rid of its signi=
ficance will only open the gates to more nastiness.
>=20
> Okay, I think I'm cluing in to what you and Ville are saying. When referr=
ing to the relationship to N4014, you are not actually referring to the act=
ual content of the paper (or the note on why it was rejected), but rather t=
o what I assume is a discussion that went on behind the scenes. That discus=
sion was not just on the specific issue (of explicitness), but a broader di=
scussion about protecting the purity of separation between value types and =
non-value types.
I never listened to any other discussion on N4014. Value vs. non-value isn=
=E2=80=99t black and white. I can=E2=80=99t speak for Ville. But yes, it=E2=
=80=99s a broader discussion. One of the more obvious artifacts was a debat=
e over whether explicit constructors should be invoked by return statements=
, which generated about a half-dozen papers.
> And I gather what you're saying is that you want the equals sign to be th=
e line of separation between value types and non-value types - that is, whe=
n you're using an equal sign, you must be working with a value type.
>=20
> Does that correctly summarize what you and Ville are getting at?
>=20
> Assuming so, I have to disagree with the reasoning. I don't disagree with=
maintaining a bright line of separation between value types and non-value =
types (let's just go with VTs and NVTs) - what I disagree with is that the =
equal sign is worth defending for this cause. I would say that battle is ov=
er, and purity lost. Here's why:
> atomic<int> x =3D {};
>=20
> That works, but this doesn't:
> atomic<int> x =3D atomic<int>{};
Because the second example isn=E2=80=99t equivalent to the first. It=E2=80=
=99s equivalent to this:
atomic<int > x =3D { 0 };
The RHS of =3D is supposed to be a value. That=E2=80=99s why the conversion=
implemented by the copy and move constructors is =E2=80=9Clvalue-to-rvalue=
..=E2=80=9D This applies equally to initialization and assignment.
If atomic=E2=80=99s conversion constructor from its initial value were expl=
icit, then I think the default constructor would be as well.
Arguably this should work too:
atomic< int > x =3D 0;
I do think it=E2=80=99s a bit silly to convert to a temporary before initia=
lizing the named variable, but I can=E2=80=99t comment further without digg=
ing into the history of the language.
> So logically that means that the first statement is not really constructi=
ng an atomic on the right - it's (in essence) assigning (which is really a =
conversion construction) the (empty) list object on the right to the atomic=
on the left.
>=20
> But if that's so, then why doesn't it work with types with an explicit de=
fault constructor?
>=20
> The fact that it fails when the constructor is explicit implies that ther=
e must be (implicitly) an atomic<int> construction going on on the right. I=
mean, you can't sanely argue that whatever is being constructed on the lef=
t isn't explicitly an atomic<int>, right?
On the right, just a plain int. If it were really atomic, then special sema=
ntics would apply to evaluating it for the sake of making a copy. (More so =
for non-lock-free types.)
True, you=E2=80=99re proposing to guarantee elision of that copy. But copy =
elision was never intended as a pillar of the language. Things are supposed=
to work without it; it=E2=80=99s not a failsafe bypass around the lvalue-t=
o-rvalue conversion.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--Apple-Mail=_09CFDD7F-7526-48BB-B89E-27A834E77CC6
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"><meta http-equiv=3D"Content-Type" content=3D"text/html charset=3D=
utf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: spac=
e; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><div c=
lass=3D""><blockquote type=3D"cite" class=3D""><div class=3D"">On 2015=E2=
=80=9309=E2=80=9311, at 12:02 PM, Mark A. Gibbs <<a href=3D"mailto:indi.=
in.the.wired@gmail.com" class=3D"">indi.in.the.wired@gmail.com</a>> wrot=
e:</div><br class=3D"Apple-interchange-newline"><div class=3D""><div dir=3D=
"ltr" class=3D""><div class=3D"">Most of my best students are those who too=
k the initiative to figure things out in the language via experimentation. =
When you can't do that - or worse, as in this situation, when experimentati=
on leads you confidently to the wrong answer - that means the language simp=
ly doesn't make sense. I don't think the correct answer to that dilemma is =
"you shouldn't experiment". The problem is not the student, it's the langua=
ge.<br class=3D""></div></div></div></blockquote><div class=3D""><br class=
=3D""></div><div class=3D"">I didn=E2=80=99t say not to experiment, I said =
that you get into trouble when you lose value semantics. The problem with t=
he example is that its =E2=80=9Cexperiment=E2=80=9D just seems to be a rand=
om jumble of keywords, and then you say that the result is surprising. An e=
xperiment is something that tests a hypothesis, and the example never said =
what the student was after.</div><br class=3D""><blockquote type=3D"cite" c=
lass=3D""><div class=3D""><div dir=3D"ltr" class=3D""><div class=3D"">Nothi=
ng rules out consulting an expert, of course, but the point is that you hav=
e to know <i class=3D"">when</i> to consult an expert, and what questions t=
o ask. You can't simply walk up to a language expert and say "just tell me =
everything". All experts and help communities expect you to do your homewor=
k and come prepared only with those questions you can't figure out on your =
own. (And in this case, trying to figure it out on your own will lead you t=
o the wrong answer. Thus, we have a problem.)<br class=3D""></div></div></d=
iv></blockquote><div class=3D""><br class=3D""></div><div class=3D"">In thi=
s case, the question would be, =E2=80=9Cwhy doesn=E2=80=99t the equals sign=
work=E2=80=9D? And the answer would be, =E2=80=9Cthe right-hand side doesn=
=E2=80=99t behave as a value.=E2=80=9D</div><br class=3D""><blockquote type=
=3D"cite" class=3D""><div class=3D""><div dir=3D"ltr" class=3D""><div class=
=3D"">Actually, making the language make more sense to beginners is my prim=
ary motivation for proposing this change (but also, easier generic programm=
ing). </div></div></div></blockquote><div class=3D""><br class=3D""></div><=
div class=3D"">The flip side of regular syntax with loose semantic constrai=
nts is getting unexpected meaning from templates. Some things aren=E2=80=99=
t <i class=3D"">supposed</i> to compile.</div><br class=3D""><blockquo=
te type=3D"cite" class=3D""><div class=3D""><div dir=3D"ltr" class=3D""><di=
v class=3D"">I would love to be able to tell the people I teach, on day 1 w=
ith no hemming or hawing or qualification: "This is how you create a new ob=
ject in C++. Just do this. Auto, name, equals, type, braces, semicolon. Don=
e. Want to initialize with a specific value? Stick it in the braces. Yes, t=
here are other ways that you'll certainly see in other people's code, and i=
n time - when we cover more topics - we'll talk about the various pros, con=
s, and gotchas. For now, just do this. It works." Then I can move on to tea=
ching them actually useful things, and not have them come up to me a couple=
days later, "um, I tried to use this lock guard, and=E2=80=A6".<br class=
=3D""></div></div></div></blockquote><div class=3D""><br class=3D""></div><=
div class=3D"">There=E2=80=99s a language for that: Java. (Except, scalars =
in Java are new objects without using the <font face=3D"Courier" class=3D""=
>new</font> keyword.)</div><div class=3D""><br class=3D""></div><div class=
=3D"">The extra bits of C++ are useful to make it a richer language. We can=
=E2=80=99t just sweep them under the rug. You can use AAA as far as value s=
emantics go, but that won=E2=80=99t get you a lock guard.</div><br class=3D=
""><blockquote type=3D"cite" class=3D""><div class=3D""><div dir=3D"ltr" cl=
ass=3D""><div class=3D"">Simple things should be simple. There doesn't need=
to be a goblin lurking in every single corner of the language.<br class=3D=
""> <br class=3D""></div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">=
<div style=3D"word-wrap:break-word" class=3D"">And BTW, I agree with Ville=
=E2=80=99s that your proposal is closely aligned with N4014. They both resu=
lt from blaming the problems of non-value-semantic classes on the equals si=
gn instead of the class. The equals sign is a safety mechanism to protect y=
ou from thorny types; getting rid of its significance will only open the ga=
tes to more nastiness.</div></blockquote><div class=3D""><br class=3D"">Oka=
y, I think I'm cluing in to what you and Ville are saying. When referring t=
o the relationship to N4014, you are not actually referring to the actual c=
ontent of the paper (or the note on why it was rejected), but rather to wha=
t I assume is a discussion that went on behind the scenes. That discussion =
was not just on the specific issue (of explicitness), but a broader discuss=
ion about protecting the purity of separation between value types and non-v=
alue types.<br class=3D""></div></div></div></blockquote><div class=3D""><b=
r class=3D""></div><div class=3D"">I never listened to any other discussion=
on N4014. Value vs. non-value isn=E2=80=99t black and white. I can=E2=80=
=99t speak for Ville. But yes, it=E2=80=99s a broader discussion. One of th=
e more obvious artifacts was a debate over whether explicit constructors sh=
ould be invoked by return statements, which generated about a half-dozen pa=
pers.</div><br class=3D""><blockquote type=3D"cite" class=3D""><div class=
=3D""><div dir=3D"ltr" class=3D""><div class=3D"">And I gather what you're =
saying is that you want the equals sign to be the line of separation betwee=
n value types and non-value types - that is, when you're using an equal sig=
n, you must be working with a value type.<br class=3D""><br class=3D"">Does=
that correctly summarize what you and Ville are getting at?<br class=3D"">=
<br class=3D"">Assuming so, I have to disagree with the reasoning. I don't =
disagree with maintaining a bright line of separation between value types a=
nd non-value types (let's just go with VTs and NVTs) - what I disagree with=
is that the equal sign is worth defending for this cause. I would say that=
battle is over, and purity lost. Here's why:<br class=3D""><div class=3D"p=
rettyprint" style=3D"background-color: rgb(250, 250, 250); border-color: rg=
b(187, 187, 187); border-style: solid; border-width: 1px; word-wrap: break-=
word;"><code class=3D"prettyprint">atomic<span style=3D"color: #080;" class=
=3D"styled-by-prettify"><int></span> x <span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">=3D</span> <span style=3D"color: #660;" class=
=3D"styled-by-prettify">{};</span></code></div><br class=3D"">That works, b=
ut this doesn't:<br class=3D""><div class=3D"prettyprint" style=3D"backgrou=
nd-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-styl=
e: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"prettyp=
rint">atomic<span style=3D"color: #080;" class=3D"styled-by-prettify"><i=
nt></span> x <span style=3D"color: #660;" class=3D"styled-by-prettify">=
=3D</span> atomic<span style=3D"color: #080;" class=3D"styled-by-prettify">=
<int></span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>{};</span></code></div></div></div></div></blockquote><div class=3D""><br =
class=3D""></div><div class=3D"">Because the second example isn=E2=80=99t e=
quivalent to the first. It=E2=80=99s equivalent to this:</div><div class=3D=
""><br class=3D""></div><div class=3D""><font face=3D"Courier" class=3D"">a=
tomic<int > x =3D { 0 };</font></div><div class=3D""><br class=3D""><=
/div>The RHS of <span style=3D"font-family: Courier;" class=3D"">=3D</=
span> is supposed to be a value. That=E2=80=99s why the conversion imp=
lemented by the copy and move constructors is =E2=80=9Clvalue-to-rvalue.=E2=
=80=9D This applies equally to initialization and assignment.</div><div cla=
ss=3D""><br class=3D""></div><div class=3D"">If <span style=3D"font-fa=
mily: Courier;" class=3D"">atomic</span>=E2=80=99s conversion constructor f=
rom its initial value were <font face=3D"Courier" class=3D"">explicit</font=
>, then I think the default constructor would be as well.</div><div class=
=3D""><br class=3D""></div><div class=3D"">Arguably this should work too:</=
div><div class=3D""><br class=3D""></div><div class=3D""><div class=3D""><f=
ont face=3D"Courier" class=3D"">atomic< int > x =3D 0;</font></div><d=
iv class=3D""><br class=3D""></div><div class=3D"">I do think it=E2=80=99s =
a bit silly to convert to a temporary before initializing the named variabl=
e, but I can=E2=80=99t comment further without digging into the history of =
the language.</div><div class=3D""><br class=3D""></div><blockquote type=3D=
"cite" class=3D""><div class=3D""><div dir=3D"ltr" class=3D""><div class=3D=
"">So logically that means that the first statement is not really construct=
ing an atomic on the right - it's (in essence) assigning (which is really a=
conversion construction) the (empty) list object on the right to the atomi=
c on the left.<br class=3D""><br class=3D"">But if that's so, then why does=
n't it work with types with an explicit default constructor?<br class=3D"">=
<br class=3D"">The fact that it fails when the constructor is explicit impl=
ies that there must be (implicitly) an <span style=3D"font-family: courier =
new,monospace;" class=3D"">atomic<int></span> construction going on o=
n the right. I mean, you can't sanely argue that whatever is being construc=
ted on the left isn't explicitly an <span style=3D"font-family: courier new=
,monospace;" class=3D"">atomic<int></span>, right?<br class=3D""></di=
v></div></div></blockquote><div class=3D""><br class=3D""></div><div class=
=3D"">On the right, just a plain <font face=3D"Courier" class=3D"">int=
</font>. If it were really atomic, then special semantics would apply to ev=
aluating it for the sake of making a copy. (More so for non-lock-free types=
..)</div><div class=3D""><br class=3D""></div><div class=3D"">True, you=E2=
=80=99re proposing to guarantee elision of that copy. But copy elision was =
never intended as a pillar of the language. Things are supposed to work wit=
hout it; it=E2=80=99s not a failsafe bypass around the lvalue-to-rvalue con=
version.</div><div class=3D""><br class=3D""></div></div></body></html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--Apple-Mail=_09CFDD7F-7526-48BB-B89E-27A834E77CC6--
.
Author: "Mark A. Gibbs" <indi.in.the.wired@gmail.com>
Date: Fri, 11 Sep 2015 17:20:02 -0700 (PDT)
Raw View
------=_Part_792_264276051.1442017202613
Content-Type: multipart/alternative;
boundary="----=_Part_793_1663996698.1442017202619"
------=_Part_793_1663996698.1442017202619
Content-Type: text/plain; charset=UTF-8
On Friday, 11 September 2015 04:00:53 UTC-4, Tomasz wrote:
>
> The difference between direct and non-direct initialization give us two
> options:
> Type x = foo(); //This will compile only if there is implicit conversion
> between result of foo() and Type
> Type x(foo()); //Will compile when there is explicit conversion from
> result of foo() and Type
>
What I'm proposing has no effect whatsoever on those two forms. You can
still use them, with no change in semantics. You're not losing any
flexibility. You're gaining a method that works for all types. It may not
work precisely the way you want for a specific case, but if you have
specific needs, go ahead and use one of the other forms. No one's tying
your hands.
> Ironically the poeple that are promoting auto everywhere syntax are given
> argument about lack of unintended conversion as argument for using it.
> While use ETTI (auto x = type(expr)) acutally introduce possibility of more
> bogus one. Just think of the Herb Sutter example:
> auto x = unique_ptr<Base>{createDerived()};
> It is working correctly in case when createDerived() is retruning
> unique_ptr<Derived>. But what if it will start to return raw pointer to
> class to object that has lifetime handled eslewhere? The syntax:
> unique_ptr<Base> x = createDerived();
> Will catch such change at compile time.
>
Okay, here's my counter example:
int get_count();
// Then later get_count() is changed to return a long. Or std::size_t.
int n = get_count(); // This will fail to detect the change. Bug reports of
// counts of -1234 objects ensue.
auto n = int{get_count()}; // This will detect the issue at compile time.
Now, as for my analysis of your example: When you change the interface
contract of a function, and either don't change the return type - or change
it to a type that is implicitly convertible to the original type in some
situations - I don't know how you can seriously expect to rely on the
language to save you from yourself.
No initialization syntax is perfect. But the difference between your
example and mine is that mine is a plausible update to a code base to
accommodate growth, whereas yours is really just a really dumb refactoring
decision that someone hoped that compiler would spare them from the
consequences of. The "auto" version catches the plausible modification, but
misses the terrible refactoring job. The non-"auto" version catches the
really dumb change that should never happen, but fails to catch the
plausible modification. Frankly, I'd prefer the "auto" result, in practice.
Oh, also, the "auto" version will crash the very first time the code that
puts the result of createDerived() in a unique_ptr gets called - basically
day 1 of testing - and debug mode will give you a message about the
double-delete... meanwhile the bug in the non-"auto" version could go for
years without being detected, unless and and until there happens to be a
case when the result of get_count() is too large, which may only happen
sporadically and be hard to reproduce. Advantage: auto.
Back to your example, relying on the semantics of "type x =
factory_function();" is a bad idea. Unless you put a comment next to it
explicitly explaining that that's what you intend, you risk someone coming
along and thinking that "type x{factory_function()};" is a better idea,
because it prevents narrowing, or something similar. The smart thing to do
is this:
template <typename T, typename U>
auto as(U&& u) -> T
{
return {u};
}
auto s = as<std::chrono::seconds>(get_timeout());
// or if you prefer a different name:
auto s = implicitly_as<std::chrono::seconds>(get_timeout());
auto s = safely_as<std::chrono::seconds>(get_timeout());
That will catch unwanted explicit conversions... and it will catch
narrowing (and if you don't want that, drop the braces)... *and* it is
self-documenting in code. And if you don't use the auto there, you have to
repeat the type, which is a bad idea. For auto, I think that's game, set,
and match.
Perhaps those of us who want to "force" everyone to use the "shiny new auto"
have given this a bit more thought than you give us credit for.
Anyway, to be clear, I am not proposing a way to initialize objects that
will solve every single possible problem imaginable. I am just proposing a
way that will work for every type, and do a sensible thing in all cases. It
may not work precisely the way you need it to for your specific instance,
in which case you can use a more specific form.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_793_1663996698.1442017202619
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Friday, 11 September 2015 04:00:53 UTC-4, Tomasz wrote=
:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bo=
rder-left: 1px #ccc solid;padding-left: 1ex;">The difference between direct=
and non-direct initialization give us two options:<br><div>Type x =3D foo(=
);=C2=A0 //This will compile only if there is implicit conversion between r=
esult of foo() and Type<br>Type x(foo()); //Will compile when there is expl=
icit conversion from result of foo() and Type<br></div></blockquote><div><b=
r>What I'm proposing has no effect whatsoever on those two forms. You c=
an still use them, with no change in semantics. You're not losing any f=
lexibility. You're gaining a method that works for all types. It may no=
t work precisely the way you want for a specific case, but if you have spec=
ific needs, go ahead and use one of the other forms. No one's tying you=
r hands.<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div>I=
ronically the poeple that are promoting auto everywhere syntax are given ar=
gument about lack of unintended conversion as argument for using it. While =
use ETTI (auto x =3D type(expr)) acutally introduce possibility of more bog=
us one. Just think of the Herb Sutter example:<br>auto x =3D unique_ptr<=
Base>{<wbr>createDerived()};<br>It is working correctly in case when cre=
ateDerived() is retruning unique_ptr<Derived>. But what if it will st=
art to return raw pointer to class to object that has lifetime handled esle=
where? The syntax:<br>unique_ptr<Base> x =3D createDerived();<br>Will=
catch such change at compile time.<br></div></blockquote><div>=C2=A0<br>Ok=
ay, here's my counter example:<br><div class=3D"prettyprint" style=3D"b=
ackground-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); bord=
er-style: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"=
prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">int</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> get_count</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">();</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br><br></span><span style=3D"color: #800;" class=3D"styled-by-=
prettify">// Then later get_count() is changed to return a long. Or std::si=
ze_t.</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><=
br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">int</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> n </span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> get_count</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">();</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> =C2=A0</span><span style=3D"color:=
#800;" class=3D"styled-by-prettify">// This will fail to detect the change=
.. Bug reports of</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 </span><span style=3D"color: #800;" class=3D"styled-by-pretti=
fy">// counts of -1234 objects ensue.</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"><br><br></span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> n </span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">int<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">get_count</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">()};</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0</span><span style=
=3D"color: #800;" class=3D"styled-by-prettify">// This will detect the issu=
e at compile time.</span></div></code></div><br>Now, as for my analysis of =
your example: When you change the interface contract of a function, and eit=
her don't change the return type - or change it to a type that is impli=
citly convertible to the original type in some situations - I don't kno=
w how you can seriously expect to rely on the language to save you from you=
rself.<br><br>No initialization syntax is perfect. But the difference betwe=
en your example and mine is that mine is a plausible update to a code base =
to accommodate growth, whereas yours is really just a really dumb refactori=
ng decision that someone hoped that compiler would spare them from the cons=
equences of. The "<span style=3D"font-family: courier new,monospace;">=
auto</span>" version catches the plausible modification, but misses th=
e terrible refactoring job. The non-"<span style=3D"font-family: couri=
er new,monospace;">auto</span>" version catches the really dumb change=
that should never happen, but fails to catch the plausible modification. F=
rankly, I'd prefer the "<span style=3D"font-family: courier new,mo=
nospace;">auto</span>" result, in practice. Oh, also, the "<span =
style=3D"font-family: courier new,monospace;">auto</span>" version wil=
l crash the very first time the code that puts the result of <span style=3D=
"font-family: courier new,monospace;">createDerived()</span> in a <span sty=
le=3D"font-family: courier new,monospace;">unique_ptr</span> gets called - =
basically day 1 of testing - and debug mode will give you a message about t=
he double-delete... meanwhile the bug in the non-"<span style=3D"font-=
family: courier new,monospace;">auto</span>" version could go for year=
s without being detected, unless and and until there happens to be a case w=
hen the result of <span style=3D"font-family: courier new,monospace;">get_c=
ount()</span> is too large, which may only happen sporadically and be hard =
to reproduce. Advantage: <span style=3D"font-family: courier new,monospace;=
">auto</span>.<br><br>Back to your example, relying on the semantics of &qu=
ot;<span style=3D"font-family: courier new,monospace;">type x =3D factory_f=
unction();</span>" is a bad idea. Unless you put a comment next to it =
explicitly explaining that that's what you intend, you risk someone com=
ing along and thinking that "<span style=3D"font-family: courier new,m=
onospace;">type x{factory_function()};</span>" is a better idea, becau=
se it prevents narrowing, or something similar. The smart thing to do is th=
is:<br><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, =
250); border-color: rgb(187, 187, 187); border-style: solid; border-width: =
1px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subp=
rettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">templ=
ate</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #660;" class=3D"styled-by-prettify"><</span><span=
style=3D"color: #008;" class=3D"styled-by-prettify">typename</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> T</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">typename</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> U</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">></span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: #008;" class=3D"styled-by-prettify">as</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">U</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">&&</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> u</span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">-></span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> T<br></span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
=C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">ret=
urn</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">u</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">};</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br><br></span><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> s </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">as</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify"><</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">std</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">chrono</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify">seconds</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">>(</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify">get_timeout</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">());</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"><br></span><span style=3D"color: #800;" class=3D"styled-by-prettify=
">// or if you prefer a different name:</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> s </span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> implicitly_as</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify"><</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
">std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify">chrono</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">seconds</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">>(</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">get_timeout</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">());</span><span style=3D"color:=
#000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> s </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> safely_as</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify"><</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify">std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify">chrono</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify">seconds</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">>(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">get_timeout</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">());</span></div></code></d=
iv><br>That will catch unwanted explicit conversions... and it will catch n=
arrowing (and if you don't want that, drop the braces)... <i>and</i> it=
is self-documenting in code. And if you don't use the <span style=3D"f=
ont-family: courier new,monospace;">auto</span> there, you have to repeat t=
he type, which is a bad idea. For <span style=3D"font-family: courier new,m=
onospace;">auto</span>, I think that's game, set, and match.<br><br>Per=
haps those of us who want to "force" everyone to use the "sh=
iny new <span style=3D"font-family: courier new,monospace;">auto</span>&quo=
t; have given this a bit more thought than you give us credit for.<br><br>A=
nyway, to be clear, I am not proposing a way to initialize objects that wil=
l solve every single possible problem imaginable. I am just proposing a way=
that will work for every type, and do a sensible thing in all cases. It ma=
y not work precisely the way you need it to for your specific instance, in =
which case you can use a more specific form.<br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_793_1663996698.1442017202619--
------=_Part_792_264276051.1442017202613--
.
Author: "Mark A. Gibbs" <indi.in.the.wired@gmail.com>
Date: Fri, 11 Sep 2015 18:48:05 -0700 (PDT)
Raw View
------=_Part_784_581471041.1442022485438
Content-Type: multipart/alternative;
boundary="----=_Part_785_1672930302.1442022485439"
------=_Part_785_1672930302.1442022485439
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Friday, 11 September 2015 04:11:43 UTC-4, David Krauss wrote:
>
> I didn=E2=80=99t say not to experiment, I said that you get into trouble =
when you=20
> lose value semantics. The problem with the example is that its =E2=80=9Ce=
xperiment=E2=80=9D=20
> just seems to be a random jumble of keywords, and then you say that the=
=20
> result is surprising.
>
That *is* saying "don't experiment", because experimenting means trying=20
things that you don't know whether they'll work or not, and learning from=
=20
the discovery of what happens. Okay, perhaps you're not saying "don't=20
experiment *ever*", but you *are* saying "don't experiment with non-value=
=20
types". Of course, the catch is that the beginner won't know that rule, and=
=20
even if they do they won't know what non-value types are, so they won't=20
know where they can or can't experiment. So, basically, "don't experiment".
Anyway, if it's just that you think the experimentation example wasn't=20
realistic, I can easily provide you with a realistic one. I've seen it=20
happen plenty of times.
=20
> An experiment is something that tests a hypothesis, and the example never=
=20
> said what the student was after.
>
Now you're just trying to be pedantic, but I can do that, too. A *science*=
=20
experiment is one that involves hypothesis testing, but even then not all=
=20
science experiments involve hypotheses: there is such a thing as=20
"exploratory data analysis". Experimentation in the general sense is merely=
=20
"trying shit to see what happens". The latter type may be non-rigorous, but=
=20
it is very often the first stage in an investigation that will be followed=
=20
up by the former type. Great scientific discoveries often start with "hm, I=
=20
wonder what happens if...".
(Also, in the original example, there *was* a hypothesis being tested.=20
Specifically, that one of the four special member functions copy/move=20
construct/assign was being used in that initialization statement. The=20
experiment was putting markers in the four functions to reveal which. You=
=20
could consider that a "closed testing procedure" that tests multiple=20
hypotheses - in this case, 4, each with its own null hypothesis -=20
simultaneously.)
=20
> In this case, the question would be, =E2=80=9Cwhy doesn=E2=80=99t the equ=
als sign work=E2=80=9D?
>
Actually, the question is not "why doesn't the equal sign work", because "a=
tomic<int>=20
a =3D {};" works but "atomic<int> a =3D atomic<int>{};" doesn't. Clearly th=
e=20
equal sign does work. The question is why doesn't it work when I write the=
=20
type twice, even though the braces on the right appear to be implying a=20
default constructed atomic on the right that is being "put" in the atomic=
=20
on the left - or aliased by the variable being declared on the left. And=20
this behaviour appears to be what that construct implies, because that's=20
what apparently happens according to "atomic<int> a =3D 0;" (doesn't work=
=20
because non-copy/non-movable) and "tuple<int> t =3D {0};" (doesn't work=20
because construction on the right is implicit).
I suggest that you are making a mistake by trying to interpret "type x =3D=
=20
type{...};" as an assignment between two values. Firstly, that seems a=20
suspicious argument right from the get go, because you don't have two=20
values. In fact, you have none before, then one after. And unlike all other=
=20
forms of initialization, in the interim you have two objects that were=20
constructed out of whole cloth right there in the statement, unobservably=
=20
(because of elision). (This is different from the cases of "type x =3D val;=
"=20
and "type x =3D func_yielding_rvalue();", because in both those two cases,=
=20
the RHS value is constructed elsewhere (though possibly elided).) The=20
argument that you really, really want this ghost object that never really=
=20
exists seems weak.
Secondly, the language refutes that interpretation. If a non-copy/non-move=
=20
type has a constructor that takes an int, but no assignment operators that=
=20
take an int, this still works: "type x =3D {0};". How can that be if this i=
s=20
actually a transfer of values? The type has no way to take an int (or an=20
initializer list) except by construction, so it must therefore be=20
constructing on the right... but that can't be, because the type is=20
non-copy/non-movable, so if it were constructed on the right, it can't=20
possibly be transferred to the left. Therefore there cannot be two values=
=20
in that statement - there must only be one, the object on the right=20
constructed with the int on the left. (Of course, the language then turns=
=20
around and screws you again, if that constructor is explicit. As I keep=20
saying, I think you're barking up the wrong tree trying to argue for=20
consistency in construction statements. That ship has sailed.)
=20
> And the answer would be, =E2=80=9Cthe right-hand side doesn=E2=80=99t beh=
ave as a value.=E2=80=9D
>
=20
Yet this works:
auto&& x =3D std::atomic<int>{};
So clearly the claim that "=3D" only works with value types just doesn't ho=
ld=20
water.
"=3D" may be the dividing line between value types and non-value types in=
=20
general code - when it is actually being used as an assignment. But in the=
=20
context of initialization, it isn't, at least not consistently.
The flip side of regular syntax with loose semantic constraints is getting=
=20
> unexpected meaning from templates. Some things aren=E2=80=99t *supposed* =
to=20
> compile.
>
But as I pointed out, that argument doesn't really apply to declarations of=
=20
the form "type x =3D type{...};". *Nobody* writes code like that with the=
=20
expectation that it is the only thing keeping non-copy/non-move types out=
=20
the door. Almost 20 years of C++ and 10 years of teaching it, I have never=
=20
seen that done (and I've seen some crazy shit). Anybody who does that is=20
being "clever" to the point of frustrating future maintenance of the code,=
=20
so there is no reason the standard should have to bless that behaviour.=20
There are better ways to prevent generic code from compiling in the face of=
=20
a non-value type. We just don't need this particular case.
Also, I'm not proposing "loose" semantic constraints. I'm proposing very=20
rigorous constraints... just constraints that are different from the=20
existing ones in one specific context (which are specious).
You're making it sound like I'm proposing throwing all distinction between=
=20
value and non-value types out - or perhaps removing the ability for "=3D" t=
o=20
distinguish in all cases. That's not so. I'm talking about taking one...=20
specific... instance - just "type x =3D type{...};", and not even "type x =
=3D=20
val;" or "type x =3D func();", those should still fail in the absence of=20
copy/move ops - in a context where there are already lots of special cases=
=20
and exceptions (initialization), and for the gain of ending the madness of=
=20
having no way to construct a new object that works for all types. I think=
=20
we can let this one go.
There=E2=80=99s a language for that: Java. (Except, scalars in Java are new=
objects=20
> without using the new keyword.)
>
I realize you're invoking Java as the exemplar of a language that prefers=
=20
simplicity and consistency at the expense of flexibility, expressiveness=20
and power... exactly what we don't want C++ to become. But frankly, if a=20
bad language has a good idea... I'm a-gonna take it. I don't care if the=20
rest of the design in that language is misguided - if it has something that=
=20
works well, and it can be done in C++ without sacrificing anything=20
important... yeah, I'll steal from Java. I don't have so much pride that I=
=20
would refuse a good idea just because of its source.
Assuming so, I have to disagree with the reasoning. I don't disagree with=
=20
> maintaining a bright line of separation between value types and non-value=
=20
> types (let's just go with VTs and NVTs) - what I disagree with is that th=
e=20
> equal sign is worth defending for this cause. I would say that battle is=
=20
> over, and purity lost. Here's why:
> atomic<int> x =3D {};
>
> That works, but this doesn't:
> atomic<int> x =3D atomic<int>{};
>
>
> Because the second example isn=E2=80=99t equivalent to the first.
>
I didn't claim they were equivalent. In fact, I obviously realize they=20
aren't because the whole point of my proposal is to *make* them equivalent.
I pointed out that the claim that "=3D" implies value semantics is false.=
=20
Atomics don't have value semantics, yet you can do "atomic<int> a =3D {};".
If it were really true that "=3D" really did imply value semantics in all=
=20
cases, then I would have to acquiesce - you would be right, and maintaining=
=20
a clear wall distinction between value types and non-value types is more=20
important than convenience. But it doesn't always imply value semantics.=20
There are already exceptions and gotchas... *especially* in the context I'm=
=20
focused on. Since the wall is already full of holes, the argument for=20
adding one more that makes things really convenient and consistent suddenly=
=20
has merit.
=20
> Arguably this should work too:
>
> atomic< int > x =3D 0;
>
> I do think it=E2=80=99s a bit silly to convert to a temporary before init=
ializing=20
> the named variable, but I can=E2=80=99t comment further without digging i=
nto the=20
> history of the language.
>
So why shouldn't this?:
atomic<int> a =3D atomic<int>{0};
What you're saying is that you think that it's reasonable that "atomic<int>=
=20
a =3D 0;" should be interpreted as "atomic<int> a{0};", and not "atomic<int=
>=20
a =3D atomic<int>{0};" (as it currently is). I agree - I see no sane reason=
=20
why it shouldn't. It's obvious what you really mean, and there's really no=
=20
reason a temporary has to be constructed then transferred to the named=20
variable.
So if that's reasonable, why is interpreting "atomic<int> a =3D=20
atomic<int>{0};" as "atomic<int> a{0};" so crazy? It's the exact... same...=
=20
reasoning: It's obvious what you really mean, and there's really no reason=
=20
a temporary has to be constructed then transferred to the named variable.
Remember, "atomic<int> a =3D {0};" is already interpreted as "atomic<int>=
=20
a{0};". "{0}" just by itself is an initializer_list<int>, yet atomic<int>=
=20
has no initializer_list<int> constructor, so that has to be what the=20
interpretation of what's happening is - the "{0}" is not "an initializer=20
list", but rather "the initializer list for the atomic being constructed".=
=20
This is already a context were the "normal" rules of "=3D" just don't apply=
..=20
What I'm proposing is basically just interpreting "atomic<int> a =3D=20
atomic<int>{0};" as "atomic<int> a atomic<int>{0};", then dropping the=20
redundant repetition of the type. (But, of course, ONLY in the case where=
=20
the type actually is repeated.)
=20
> True, you=E2=80=99re proposing to guarantee elision of that copy. But cop=
y elision=20
> was never intended as a pillar of the language. Things are supposed to wo=
rk=20
> without it; it=E2=80=99s not a failsafe bypass around the lvalue-to-rvalu=
e=20
> conversion.
>
=20
Yes, and I am proposing to change that - in this one, specific syntactic=20
construct. That's why elision is mentioned in the topic.
You're right, the current state of affairs is that elision is optional in=
=20
all cases, even in the case that I'm focused on. My argument is if we=20
change that rule just in this specific case, to make the elision=20
effectively required - and "required" to the point that there is no moving=
=20
at all, even conceptually - we gain:
- guaranteed efficiency (as opposed to almost-certain but not required=
=20
efficiency)
- and a practical solution to the initialization madness that works in=
=20
all cases (though may not do precisely what you specifically need in a=
=20
specific case, in which case you still have the other options).
=20
The only purposes behind keeping the requirement that the type be=20
copy/movable are either a) to maintain language purity wrt the distinction=
=20
of value/non-value types, or b) because it is a practical way to actually=
=20
distinguish between value/non-value types in generic code.
For (a), I say that goal is already a lost cause, in this context. There=20
are so many peculiarities in the interpretations of the various=20
construction syntaxes, that this doesn't really seem the right place to be=
=20
adamant about drawing this line.
For (b), I say: nobody does it for that purpose, nobody would understand=20
that's what the intention was if it was actually used for that purpose,=20
there are several other - better - ways of achieving the same goal, and=20
finally, it just don't work anyway. There are more requirements to having=
=20
value semantics than just being copy/movable, so a type that does not have=
=20
value semantics but is copy/movable would pass the bar.
Given that the syntax doesn't actually distinguish anything but whether the=
=20
type is non-copy/non-movable or not - it doesn't actually serve the purpose=
=20
of detecting value semantics - and that construction in general is already=
=20
a context where some things that look like copies/moves are not actually, I=
=20
think we can get away with repurposing it, and gaining clarity and sanity=
=20
in one of the most basic and important parts of the language: constructing=
=20
objects.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_785_1672930302.1442022485439
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Friday, 11 September 2015 04:11:43 UTC-4, David Krauss =
wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.=
8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div style=3D"word-wrap=
:break-word"><div>I didn=E2=80=99t say not to experiment, I said that you g=
et into trouble when you lose value semantics. The problem with the example=
is that its =E2=80=9Cexperiment=E2=80=9D just seems to be a random jumble =
of keywords, and then you say that the result is surprising.</div></div></b=
lockquote><div><br>That <i>is</i> saying "don't experiment", =
because experimenting means trying things that you don't know whether t=
hey'll work or not, and learning from the discovery of what happens. Ok=
ay, perhaps you're not saying "don't experiment <i>ever</i>&qu=
ot;, but you <i>are</i> saying "don't experiment with non-value ty=
pes". Of course, the catch is that the beginner won't know that ru=
le, and even if they do they won't know what non-value types are, so th=
ey won't know where they can or can't experiment. So, basically, &q=
uot;don't experiment".<br><br>Anyway, if it's just that you th=
ink the experimentation example wasn't realistic, I can easily provide =
you with a realistic one. I've seen it happen plenty of times.<br>=C2=
=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: =
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div style=3D"word-wr=
ap:break-word"><div>An experiment is something that tests a hypothesis, and=
the example never said what the student was after.<br></div></div></blockq=
uote><div><br>Now you're just trying to be pedantic, but I can do that,=
too. A <i>science</i> experiment is one that involves hypothesis testing, =
but even then not all science experiments involve hypotheses: there is such=
a thing as "exploratory data analysis". Experimentation in the g=
eneral sense is merely "trying shit to see what happens". The lat=
ter type may be non-rigorous, but it is very often the first stage in an in=
vestigation that will be followed up by the former type. Great scientific d=
iscoveries often start with "hm, I wonder what happens if...".<br=
><br>(Also, in the original example, there <i>was</i> a hypothesis being te=
sted. Specifically, that one of the four special member functions copy/move=
construct/assign was being used in that initialization statement. The expe=
riment was putting markers in the four functions to reveal which. You could=
consider that a "closed testing procedure" that tests multiple h=
ypotheses - in this case, 4, each with its own null hypothesis - simultaneo=
usly.)<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;=
margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div sty=
le=3D"word-wrap:break-word"><div><div>In this case, the question would be, =
=E2=80=9Cwhy doesn=E2=80=99t the equals sign work=E2=80=9D?</div></div></di=
v></blockquote><div><br>Actually, the question is not "why doesn't=
the equal sign work", because "<span style=3D"font-family: couri=
er new,monospace;">atomic<int> a =3D {};</span>" works but "=
;<span style=3D"font-family: courier new,monospace;">atomic<int> a =
=3D atomic<int>{};</span>" doesn't. Clearly the equal sign d=
oes work. The question is why doesn't it work when I write the type twi=
ce, even though the braces on the right appear to be implying a default con=
structed atomic on the right that is being "put" in the atomic on=
the left - or aliased by the variable being declared on the left. And this=
behaviour appears to be what that construct implies, because that's wh=
at apparently happens according to "<span style=3D"font-family: courie=
r new,monospace;">atomic<int> a =3D 0;</span>" (doesn't work=
because non-copy/non-movable) and "<span style=3D"font-family: courie=
r new,monospace;">tuple<int> t =3D {0};</span>" (doesn't wor=
k because construction on the right is implicit).<br><br>I suggest that you=
are making a mistake by trying to interpret "<span style=3D"font-fami=
ly: courier new,monospace;">type x =3D type{...};</span>" as an assign=
ment between two values. Firstly, that seems a suspicious argument right fr=
om the get go, because you don't have two values. In fact, you have non=
e before, then one after. And unlike all other forms of initialization, in =
the interim you have two objects that were constructed out of whole cloth r=
ight there in the statement, unobservably (because of elision). (This is di=
fferent from the cases of "<span style=3D"font-family: courier new,mon=
ospace;">type x =3D val;</span>" and "<span style=3D"font-family:=
courier new,monospace;">type x =3D func_yielding_rvalue();</span>", b=
ecause in both those two cases, the RHS value is constructed elsewhere (tho=
ugh possibly elided).) The argument that you really, really want this ghost=
object that never really exists seems weak.<br><br>Secondly, the language =
refutes that interpretation. If a non-copy/non-move type has a constructor =
that takes an int, but no assignment operators that take an int, this still=
works: "<span style=3D"font-family: courier new,monospace;">type x =
=3D {0};</span>". How can that be if this is actually a transfer of va=
lues? The type has no way to take an int (or an initializer list) except by=
construction, so it must therefore be constructing on the right... but tha=
t can't be, because the type is non-copy/non-movable, so if it were con=
structed on the right, it can't possibly be transferred to the left. Th=
erefore there cannot be two values in that statement - there must only be o=
ne, the object on the right constructed with the int on the left. (Of cours=
e, the language then turns around and screws you again, if that constructor=
is explicit. As I keep saying, I think you're barking up the wrong tre=
e trying to argue for consistency in construction statements. That ship has=
sailed.)<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:=
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div =
style=3D"word-wrap:break-word"><div><div>And the answer would be, =E2=80=9C=
the right-hand side doesn=E2=80=99t behave as a value.=E2=80=9D</div></div>=
</div></blockquote><div>=C2=A0<br>Yet this works:<br><div class=3D"prettypr=
int" style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, =
187, 187); border-style: solid; border-width: 1px; word-wrap: break-word;">=
<code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">&&</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> x </span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> std</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">atomic</span><span style=3D"color: #080;" class=3D"styled-by-prettif=
y"><int></span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">{};</span></div></code></div><br>So clearly the claim that "=3D&qu=
ot; only works with value types just doesn't hold water.<br><br>"=
=3D" may be the dividing line between value types and non-value types =
in general code - when it is actually being used as an assignment. But in t=
he context of initialization, it isn't, at least not consistently.<br><=
br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: =
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div style=3D"word-wr=
ap:break-word"><div><div>The flip side of regular syntax with loose semanti=
c constraints is getting unexpected meaning from templates. Some things are=
n=E2=80=99t <i>supposed</i>=C2=A0to compile.</div></div></div></blockquote>=
<div><br>But as I pointed out, that argument doesn't really apply to de=
clarations of the form "<span style=3D"font-family: courier new,monosp=
ace;">type x =3D type{...};</span>". <i>Nobody</i> writes code like th=
at with the expectation that it is the only thing keeping non-copy/non-move=
types out the door. Almost 20 years of C++ and 10 years of teaching it, I =
have never seen that done (and I've seen some crazy shit). Anybody who =
does that is being "clever" to the point of frustrating future ma=
intenance of the code, so there is no reason the standard should have to bl=
ess that behaviour. There are better ways to prevent generic code from comp=
iling in the face of a non-value type. We just don't need this particul=
ar case.<br><br>Also, I'm not proposing "loose" semantic cons=
traints. I'm proposing very rigorous constraints... just constraints th=
at are different from the existing ones in one specific context (which are =
specious).<br><br>You're making it sound like I'm proposing throwin=
g all distinction between value and non-value types out - or perhaps removi=
ng the ability for "=3D" to distinguish in all cases. That's =
not so. I'm talking about taking one... specific... instance - just &qu=
ot;<span style=3D"font-family: courier new,monospace;">type x =3D type{...}=
;</span>", and not even "<span style=3D"font-family: courier new,=
monospace;">type x =3D val;</span>" or "<span style=3D"font-famil=
y: courier new,monospace;">type x =3D func();</span>", those should st=
ill fail in the absence of copy/move ops - in a context where there are alr=
eady lots of special cases and exceptions (initialization), and for the gai=
n of ending the madness of having no way to construct a new object that wor=
ks for all types. I think we can let this one go.<br><br></div><blockquote =
class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1p=
x #ccc solid;padding-left: 1ex;"><div style=3D"word-wrap:break-word"><div>T=
here=E2=80=99s a language for that: Java. (Except, scalars in Java are new =
objects without using the <font face=3D"Courier">new</font> keyword.)</div>=
</div></blockquote><div><br>I realize you're invoking Java as the exemp=
lar of a language that prefers simplicity and consistency at the expense of=
flexibility, expressiveness and power... exactly what we don't want C+=
+ to become. But frankly, if a bad language has a good idea... I'm a-go=
nna take it. I don't care if the rest of the design in that language is=
misguided - if it has something that works well, and it can be done in C++=
without sacrificing anything important... yeah, I'll steal from Java. =
I don't have so much pride that I would refuse a good idea just because=
of its source.<br><br></div><blockquote class=3D"gmail_quote" style=3D"mar=
gin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><=
div style=3D"word-wrap:break-word"><div><blockquote type=3D"cite"><div><div=
dir=3D"ltr"><div>Assuming so, I have to disagree with the reasoning. I don=
't disagree with maintaining a bright line of separation between value =
types and non-value types (let's just go with VTs and NVTs) - what I di=
sagree with is that the equal sign is worth defending for this cause. I wou=
ld say that battle is over, and purity lost. Here's why:<br><div style=
=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);border-=
style:solid;border-width:1px;word-wrap:break-word"><code>atomic<span style=
=3D"color:#080"><int></span> x <span style=3D"color:#660">=3D</span> =
<span style=3D"color:#660">{};</span></code></div><br>That works, but this =
doesn't:<br><div style=3D"background-color:rgb(250,250,250);border-colo=
r:rgb(187,187,187);border-style:solid;border-width:1px;word-wrap:break-word=
"><code>atomic<span style=3D"color:#080"><int></span> x <span style=
=3D"color:#660">=3D</span> atomic<span style=3D"color:#080"><int></sp=
an><span style=3D"color:#660">{};</span></code></div></div></div></div></bl=
ockquote><div><br></div><div>Because the second example isn=E2=80=99t equiv=
alent to the first.</div></div></div></blockquote><div><br>I didn't cla=
im they were equivalent. In fact, I obviously realize they aren't becau=
se the whole point of my proposal is to <i>make</i> them equivalent.<br><br=
>I pointed out that the claim that "=3D" implies value semantics =
is false. Atomics don't have value semantics, yet you can do "<spa=
n style=3D"font-family: courier new,monospace;">atomic<int> a =3D {};=
</span>".<br><br>If it were really true that "=3D" really di=
d imply value semantics in all cases, then I would have to acquiesce - you =
would be right, and maintaining a clear wall distinction between value type=
s and non-value types is more important than convenience. But it doesn'=
t always imply value semantics. There are already exceptions and gotchas...=
<i>especially</i> in the context I'm focused on. Since the wall is alr=
eady full of holes, the argument for adding one more that makes things real=
ly convenient and consistent suddenly has merit.<br>=C2=A0</div><blockquote=
class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1=
px #ccc solid;padding-left: 1ex;"><div style=3D"word-wrap:break-word">Argua=
bly this should work too:<div><br></div><div><div><font face=3D"Courier">at=
omic< int > x =3D 0;</font></div><div><br></div><div>I do think it=E2=
=80=99s a bit silly to convert to a temporary before initializing the named=
variable, but I can=E2=80=99t comment further without digging into the his=
tory of the language.</div></div></div></blockquote><div><br>So why shouldn=
't this?:<br><div class=3D"prettyprint" style=3D"background-color: rgb(=
250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; bord=
er-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div cla=
ss=3D"subprettyprint"><span style=3D"color: #000;" class=3D"styled-by-prett=
ify">atomic</span><span style=3D"color: #080;" class=3D"styled-by-prettify"=
><int></span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> a </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> atomic</spa=
n><span style=3D"color: #080;" class=3D"styled-by-prettify"><int></sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span =
style=3D"color: #066;" class=3D"styled-by-prettify">0</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">};</span></div></code></div><br>=
What you're saying is that you think that it's reasonable that &quo=
t;<span style=3D"font-family: courier new,monospace;">atomic<int> a =
=3D 0;</span>" should be interpreted as "<span style=3D"font-fami=
ly: courier new,monospace;">atomic<int> a{0};</span>", and not &=
quot;<span style=3D"font-family: courier new,monospace;">atomic<int> =
a =3D atomic<int>{0};</span>" (as it currently is). I agree - I =
see no sane reason why it shouldn't. It's obvious what you really m=
ean, and there's really no reason a temporary has to be constructed the=
n transferred to the named variable.<br><br>So if that's reasonable, wh=
y is interpreting "<span style=3D"font-family: courier new,monospace;"=
>atomic<int> a =3D atomic<int>{0};</span>" as "<span =
style=3D"font-family: courier new,monospace;">atomic<int> a{0};</span=
>" so crazy? It's the exact... same... reasoning: It's obvious=
what you really mean, and there's really no reason a temporary has to =
be constructed then transferred to the named variable.<br><br>Remember, &qu=
ot;<span style=3D"font-family: courier new,monospace;">atomic<int> a =
=3D {0};</span>" is already interpreted as "<span style=3D"font-f=
amily: courier new,monospace;">atomic<int> a{0};</span>". "=
<span style=3D"font-family: courier new,monospace;">{0}</span>" just b=
y itself is an <span style=3D"font-family: courier new,monospace;">initiali=
zer_list<int></span>, yet <span style=3D"font-family: courier new,mon=
ospace;">atomic<int></span> has no <span style=3D"font-family: courie=
r new,monospace;">initializer_list<int></span> constructor, so that h=
as to be what the interpretation of what's happening is - the "<sp=
an style=3D"font-family: courier new,monospace;">{0}</span>" is not &q=
uot;an initializer list", but rather "the initializer list for th=
e atomic being constructed". This is already a context were the "=
normal" rules of "=3D" just don't apply. What I'm pr=
oposing is basically just interpreting "<span style=3D"font-family: co=
urier new,monospace;">atomic<int> a =3D atomic<int>{0};</span>&=
quot; as "<span style=3D"font-family: courier new,monospace;">atomic&l=
t;int> a atomic<int>{0};</span>", then dropping the redundant=
repetition of the type. (But, of course, ONLY in the case where the type a=
ctually is repeated.)<br>=C2=A0</div><blockquote class=3D"gmail_quote" styl=
e=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left:=
1ex;"><div style=3D"word-wrap:break-word"><div>True, you=E2=80=99re propos=
ing to guarantee elision of that copy. But copy elision was never intended =
as a pillar of the language. Things are supposed to work without it; it=E2=
=80=99s not a failsafe bypass around the lvalue-to-rvalue conversion.</div>=
</div></blockquote><div>=C2=A0<br>Yes, and I am proposing to change that - =
in this one, specific syntactic construct. That's why elision is mentio=
ned in the topic.<br><br>You're right, the current state of affairs is =
that elision is optional in all cases, even in the case that I'm focuse=
d on. My argument is if we change that rule just in this specific case, to =
make the elision effectively required - and "required" to the poi=
nt that there is no moving at all, even conceptually - we gain:<br><ul><li>=
guaranteed efficiency (as opposed to almost-certain but not required effici=
ency)</li><li>and a practical solution to the initialization madness that w=
orks in all cases (though may not do precisely what you specifically need i=
n a specific case, in which case you still have the other options).<br></li=
></ul>The only purposes behind keeping the requirement that the type be cop=
y/movable are either a) to maintain language purity wrt the distinction of =
value/non-value types, or b) because it is a practical way to actually dist=
inguish between value/non-value types in generic code.<br><br>For (a), I sa=
y that goal is already a lost cause, in this context. There are so many pec=
uliarities in the interpretations of the various construction syntaxes, tha=
t this doesn't really seem the right place to be adamant about drawing =
this line.<br><br>For (b), I say: nobody does it for that purpose, nobody w=
ould understand that's what the intention was if it was actually used f=
or that purpose, there are several other - better - ways of achieving the s=
ame goal, and finally, it just don't work anyway. There are more requir=
ements to having value semantics than just being copy/movable, so a type th=
at does not have value semantics but is copy/movable would pass the bar.<br=
><br>Given that the syntax doesn't actually distinguish anything but wh=
ether the type is non-copy/non-movable or not - it doesn't actually ser=
ve the purpose of detecting value semantics - and that construction in gene=
ral is already a context where some things that look like copies/moves are =
not actually, I think we can get away with repurposing it, and gaining clar=
ity and sanity in one of the most basic and important parts of the language=
: constructing objects.<br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_785_1672930302.1442022485439--
------=_Part_784_581471041.1442022485438--
.
Author: David Krauss <potswa@gmail.com>
Date: Sat, 12 Sep 2015 13:31:33 +0800
Raw View
--Apple-Mail=_7A1D8298-3492-4F26-A630-25C39AA7AA37
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
> On 2015=E2=80=9309=E2=80=9312, at 9:48 AM, Mark A. Gibbs <indi.in.the.wir=
ed@gmail.com> wrote:
>=20
> On Friday, 11 September 2015 04:11:43 UTC-4, David Krauss wrote:
> I didn=E2=80=99t say not to experiment, I said that you get into trouble =
when you lose value semantics. The problem with the example is that its =E2=
=80=9Cexperiment=E2=80=9D just seems to be a random jumble of keywords, and=
then you say that the result is surprising.
>=20
> That is saying "don't experiment", because experimenting means trying thi=
ngs that you don't know whether they'll work or not,
How can you say whether something =E2=80=9Cworked=E2=80=9D if there was no =
goal in the first place? You only mentioned "Wanting to explore constructor=
s and destructors,=E2=80=9D so from that perspective, the experiment was a =
resounding success.
> and learning from the discovery of what happens. Okay, perhaps you're not=
saying "don't experiment ever", but you are saying "don't experiment with =
non-value types". Of course, the catch is that the beginner won't know that=
rule, and even if they do they won't know what non-value types are, so the=
y won't know where they can or can't experiment. So, basically, "don't expe=
riment=E2=80=9D.
Don=E2=80=99t experiment unless you=E2=80=99re willing to discover somethin=
g new. Don=E2=80=99t try to work in a vacuum, but maintain contact with the=
community of folks with related experience. These rules apply to all acade=
mia. Especially now, StackOverflow is always just a click away.
The confusion of the student in the second part of your example was due to =
copy elision, by the way, which isn=E2=80=99t guaranteed. Compilers still i=
mplement -fno-elide-copies last I checked. Although in your example, elisio=
n can effectively be guaranteed because the initializer is a prvalue, in ot=
her cases the move constructor is still really used. To cover all the bases=
, you=E2=80=99d need to subdivide copy-initialization into more different c=
ases. It would not ultimately be a simplification, you=E2=80=99d just be sw=
eeping a few things further under the rug.
> Anyway, if it's just that you think the experimentation example wasn't re=
alistic, I can easily provide you with a realistic one. I've seen it happen=
plenty of times.
Sure, fire away.
> An experiment is something that tests a hypothesis, and the example never=
said what the student was after.
>=20
> Now you're just trying to be pedantic, but I can do that, too. A science =
experiment is one that involves hypothesis testing, but even then not all s=
cience experiments involve hypotheses: there is such a thing as "explorator=
y data analysis". Experimentation in the general sense is merely "trying sh=
it to see what happens". The latter type may be non-rigorous, but it is ver=
y often the first stage in an investigation that will be followed up by the=
former type. Great scientific discoveries often start with "hm, I wonder w=
hat happens if=E2=80=A6".
If the student is only trying to learn the rules, then they=E2=80=99re not =
allowed to be upset when they find one.
I also recall learning about copy elision when copy constructor side effect=
s disappeared. Even back then in the 90=E2=80=99s, there was literature to =
connect the surprising result to class value semantics, and turn the =E2=80=
=9Cexploratory data analysis=E2=80=9D into a valuable learning experience.
Copy elision isn=E2=80=99t remotely new, nor is the element of surprise spe=
cific to non-value-semantic classes.
> (Also, in the original example, there was a hypothesis being tested. Spec=
ifically, that one of the four special member functions copy/move construct=
/assign was being used in that initialization statement. The experiment was=
putting markers in the four functions to reveal which. You could consider =
that a "closed testing procedure" that tests multiple hypotheses - in this =
case, 4, each with its own null hypothesis - simultaneously.)
Another platform or another similar experiment would have resulted in the m=
ove constructor being called.
> In this case, the question would be, =E2=80=9Cwhy doesn=E2=80=99t the equ=
als sign work=E2=80=9D?
>=20
> Actually, the question is not "why doesn't the equal sign work", because =
"atomic<int> a =3D {};" works but "atomic<int> a =3D atomic<int>{};" doesn'=
t. Clearly the equal sign does work. The question is why doesn't it work wh=
en I write the type twice, even though the braces on the right appear to be=
implying a default constructed atomic on the right
False supposition.
> that is being "put" in the atomic on the left - or aliased by the variabl=
e being declared on the left. And this behaviour appears to be what that co=
nstruct implies, because that's what apparently happens according to "atomi=
c<int> a =3D 0;=E2=80=9D
I=E2=80=99ll grant that atomic<int> a =3D 0 should work, but only because 0=
is not an atomic. If you use {0}, there is no move (or elision) needed.
> (doesn't work because non-copy/non-movable) and "tuple<int> t =3D {0};" (=
doesn't work because construction on the right is implicit).
This is already fixed.
> I suggest that you are making a mistake by trying to interpret "type x =
=3D type{...};" as an assignment between two values. Firstly, that seems a =
suspicious argument right from the get go, because you don't have two value=
s. In fact, you have none before, then one after.
The expression type{=E2=80=A6}, like any expression, has a value. You want =
to use it as the initial value of a persistent object, but in the first pla=
ce it exists as a value, regardless of its enclosing context.
Your model doesn=E2=80=99t seem to accommodate type x =3D derived_type{};
> And unlike all other forms of initialization, in the interim you have two=
objects that were constructed out of whole cloth right there in the statem=
ent, unobservably (because of elision). (This is different from the cases o=
f "type x =3D val;" and "type x =3D func_yielding_rvalue();", because in bo=
th those two cases, the RHS value is constructed elsewhere (though possibly=
elided).) The argument that you really, really want this ghost object that=
never really exists seems weak.
>=20
> Secondly, the language refutes that interpretation. If a non-copy/non-mov=
e type has a constructor that takes an int, but no assignment operators tha=
t take an int, this still works: "type x =3D {0};=E2=80=9D.
What do assignment operators have to do with this?
> How can that be if this is actually a transfer of values? The type has no=
way to take an int (or an initializer list) except by construction, so it =
must therefore be constructing on the right... but that can't be, because t=
he type is non-copy/non-movable, so if it were constructed on the right, it=
can't possibly be transferred to the left.
An int is constructed on the right and transferred to the left. Easy peasy.
> Therefore there cannot be two values in that statement - there must only =
be one, the object on the right constructed with the int on the left. (Of c=
ourse, the language then turns around and screws you again, if that constru=
ctor is explicit. As I keep saying, I think you're barking up the wrong tre=
e trying to argue for consistency in construction statements. That ship has=
sailed.)
There=E2=80=99s plenty of literature on what explicit means, due to the rec=
ent return statement debate. Please review, for the sake of your students.
> And the answer would be, =E2=80=9Cthe right-hand side doesn=E2=80=99t beh=
ave as a value.=E2=80=9D
> =20
> Yet this works:
> auto&& x =3D std::atomic<int>{};
>=20
> So clearly the claim that "=3D" only works with value types just doesn't =
hold water.
>=20
> "=3D" may be the dividing line between value types and non-value types in=
general code - when it is actually being used as an assignment. But in the=
context of initialization, it isn't, at least not consistently.
This is temporary lifetime extension. Is it impure to use =3D for reference=
binding? Interesting thought. However, the easy answer is that the value o=
n the RHS is exactly preserved by reference binding, overriding class seman=
tics. All expressions have values, after all, and =E2=80=9Cnon-value-semant=
ic=E2=80=9D classes are only ones which may misbehave when some mathematica=
l abstraction is assumed. =E2=80=9CValue semantic=E2=80=9D refers to the no=
tion of separating a value from an object, not the existence of a value in =
the first place.
Reference binding gives expression templates conniptions: They use non-valu=
e types to represent mathematical values.
A reference stores an lvalue, i.e. an alias to an object which must remain =
valid =E2=80=94 I=E2=80=99m content to leave it at that. (Well, not exactly=
satisfied=E2=80=A6 the language should do more validation, and user-define=
d types should have access to lifetime extension as well, hence my proposal=
bit.ly/genlife <http://bit.ly/genlife>.)
> The flip side of regular syntax with loose semantic constraints is gettin=
g unexpected meaning from templates. Some things aren=E2=80=99t supposed to=
compile.
>=20
> But as I pointed out, that argument doesn't really apply to declarations =
of the form "type x =3D type{...};". Nobody writes code like that with the =
expectation that it is the only thing keeping non-copy/non-move types out t=
he door. Almost 20 years of C++ and 10 years of teaching it,
Nobody in their right mind would write type on both sides of the equals sig=
n before C++11. We=E2=80=99re both limited to 4-5 years experience with thi=
s.
> I have never seen that done (and I've seen some crazy shit). Anybody who =
does that is being "clever" to the point of frustrating future maintenance =
of the code, so there is no reason the standard should have to bless that b=
ehaviour. There are better ways to prevent generic code from compiling in t=
he face of a non-value type. We just don't need this particular case.
>=20
> Also, I'm not proposing "loose" semantic constraints. I'm proposing very =
rigorous constraints... just constraints that are different from the existi=
ng ones in one specific context (which are specious).
To me, you sound specious. But I=E2=80=99m keeping an open mind; you=E2=80=
=99re the one pacing this discussion.
> You're making it sound like I'm proposing throwing all distinction betwee=
n value and non-value types out - or perhaps removing the ability for "=3D"=
to distinguish in all cases. That's not so. I'm talking about taking one..=
.. specific... instance - just "type x =3D type{...};", and not even "type x=
=3D val;" or "type x =3D func();", those should still fail in the absence =
of copy/move ops - in a context where there are already lots of special cas=
es and exceptions (initialization), and for the gain of ending the madness =
of having no way to construct a new object that works for all types. I thin=
k we can let this one go.
What about type x =3D type{ func() }?
> There=E2=80=99s a language for that: Java. (Except, scalars in Java are n=
ew objects without using the new keyword.)
>=20
> I realize you're invoking Java as the exemplar of a language that prefers=
simplicity and consistency at the expense of flexibility, expressiveness a=
nd power... exactly what we don't want C++ to become. But frankly, if a bad=
language has a good idea... I'm a-gonna take it. I don't care if the rest =
of the design in that language is misguided - if it has something that work=
s well, and it can be done in C++ without sacrificing anything important...=
yeah, I'll steal from Java. I don't have so much pride that I would refuse=
a good idea just because of its source.
Just as there=E2=80=99s C++-as-C, there=E2=80=99s also C++-as-Java =E2=80=
=94 albeit with no garbage collector. (We should have a GC already, though!=
) Many instructors have really gone that route, to the chagrin of the rest =
of the community.
> I didn't claim they were equivalent. In fact, I obviously realize they ar=
en't because the whole point of my proposal is to make them equivalent.
>=20
> I pointed out that the claim that "=3D" implies value semantics is false.=
Atomics don't have value semantics, yet you can do "atomic<int> a =3D {};=
=E2=80=9D.
Hmm, you deleted the part where I explained that is equivalent to atomic<in=
t> a =3D {0}; and then re-asked the question.
A: atomic<int> a =3D {};
B: atomic<int> a =3D {0};
C: atomic<int> a =3D atomic<int>{};
A is equivalent to B. Not by language semantics, but because the class defi=
nes it that way.
A is not equivalent to C. You propose to make them equivalent at the langua=
ge level.
What about classes for which B is not equivalent to C?
> If it were really true that "=3D" really did imply value semantics in all=
cases, then I would have to acquiesce - you would be right, and maintainin=
g a clear wall distinction between value types and non-value types is more =
important than convenience. But it doesn't always imply value semantics. Th=
ere are already exceptions and gotchas... especially in the context I'm foc=
used on. Since the wall is already full of holes, the argument for adding o=
ne more that makes things really convenient and consistent suddenly has mer=
it.
> =20
> Arguably this should work too:
>=20
> atomic< int > x =3D 0;
>=20
> I do think it=E2=80=99s a bit silly to convert to a temporary before init=
ializing the named variable, but I can=E2=80=99t comment further without di=
gging into the history of the language.
>=20
> So why shouldn't this?:
> atomic<int> a =3D atomic<int>{0};
>=20
> What you're saying is that you think that it's reasonable that "atomic<in=
t> a =3D 0;" should be interpreted as "atomic<int> a{0};=E2=80=9D
No, I=E2=80=99m saying it=E2=80=99s reasonable to interpret it as atomic<in=
t> a =3D {0} with braces and the equals sign.
> , and not "atomic<int> a =3D atomic<int>{0};" (as it currently is). I agr=
ee - I see no sane reason why it shouldn't. It's obvious what you really me=
an, and there's really no reason a temporary has to be constructed then tra=
nsferred to the named variable.
>=20
> So if that's reasonable, why is interpreting "atomic<int> a =3D atomic<in=
t>{0};" as "atomic<int> a{0};" so crazy? It's the exact... same... reasonin=
g: It's obvious what you really mean, and there's really no reason a tempor=
ary has to be constructed then transferred to the named variable.
No, because it should be possible to substitute a function, even returning =
a derived type, on the RHS.
> Remember, "atomic<int> a =3D {0};" is already interpreted as "atomic<int>=
a{0};=E2=80=9D.
Not at the language level; those behave differently given an explicit const=
ructor.
> "{0}" just by itself is an initializer_list<int>,
Not by a long shot.
> yet atomic<int> has no initializer_list<int> constructor, so that has to =
be what the interpretation of what's happening is - the "{0}" is not "an in=
itializer list", but rather "the initializer list for the atomic being cons=
tructed". This is already a context were the "normal" rules of "=3D" just d=
on't apply.
The normal rule of =3D is lvalue-to-rvalue conversion on the RHS. As far as=
I know, pre-conversion to a temporary of the initialized type is a mere hi=
storical artifact. It would be interesting to see a well-researched proposa=
l to regularize =3D x initializers with =3D {x}. I=E2=80=99m sure the guys =
who drafted the copy-list-initialization spec thought about the difference,=
and such research should not overlook the generalized initializer list pro=
posals, which are numerous and deep.
> What I'm proposing is basically just interpreting "atomic<int> a =3D atom=
ic<int>{0};" as "atomic<int> a atomic<int>{0};", then dropping the redundan=
t repetition of the type. (But, of course, ONLY in the case where the type =
actually is repeated.)
> =20
> True, you=E2=80=99re proposing to guarantee elision of that copy. But cop=
y elision was never intended as a pillar of the language. Things are suppos=
ed to work without it; it=E2=80=99s not a failsafe bypass around the lvalue=
-to-rvalue conversion.
> =20
> Yes, and I am proposing to change that - in this one, specific syntactic =
construct. That's why elision is mentioned in the topic.
Applying it for class conversion expressions but not function calls: is tha=
t really going to improve teachability? Much less real-life usability?
Maybe it=E2=80=99s time to recognize the =E2=80=9Calmost=E2=80=9D in AAA.
> You're right, the current state of affairs is that elision is optional in=
all cases, even in the case that I'm focused on. My argument is if we chan=
ge that rule just in this specific case, to make the elision effectively re=
quired - and "required" to the point that there is no moving at all, even c=
onceptually - we gain:
> guaranteed efficiency (as opposed to almost-certain but not required effi=
ciency)
> and a practical solution to the initialization madness that works in all =
cases (though may not do precisely what you specifically need in a specific=
case, in which case you still have the other options).
> The only purposes behind keeping the requirement that the type be copy/mo=
vable are either a) to maintain language purity wrt the distinction of valu=
e/non-value types, or b) because it is a practical way to actually distingu=
ish between value/non-value types in generic code.
>=20
> For (a), I say that goal is already a lost cause, in this context. There =
are so many peculiarities in the interpretations of the various constructio=
n syntaxes, that this doesn't really seem the right place to be adamant abo=
ut drawing this line.
You seem to be implicitly admitting that others have a broader perspective =
than yourself, but that you=E2=80=99re not willing to see the forest for th=
e trees.
There=E2=80=99s no particular reason to expect AAA to work generically. It=
=E2=80=99s a recent invention since C++11, unrelated to earlier practice. M=
aybe a language can be designed around it, but a comprehensive retrofit to =
C++ is unlikely.
That said, given my accessor lifetime extension proposal and another one (n=
ot updated for Kona, but not dead) N4149 regarding expression template conv=
ersions, you could do
auto guard =3D make_guard();
wherein the =E2=80=9Cvalue=E2=80=9D of a guard cannot be moved to a new obj=
ect, but it can generate an accessor view to itself, leading to its self-pr=
eservation.
> For (b), I say: nobody does it for that purpose, nobody would understand =
that's what the intention was if it was actually used for that purpose, the=
re are several other - better - ways of achieving the same goal, and finall=
y, it just don't work anyway. There are more requirements to having value s=
emantics than just being copy/movable, so a type that does not have value s=
emantics but is copy/movable would pass the bar.
Value vs. non-value isn=E2=80=99t black and white. Not sure exactly what go=
al you=E2=80=99re supposing.
To be sure, a template over numeric types should not accept atomic<int>. It=
=E2=80=99s a facility for managing integers safely against multithreaded al=
iasing. It can store and retrieve an integer value, even up to implicitly c=
onverting both ways, but that doesn=E2=80=99t actually make it a number.
Sure, it takes time to teach that to a student. But I think that=E2=80=99s =
time well spent.
> Given that the syntax doesn't actually distinguish anything but whether t=
he type is non-copy/non-movable or not - it doesn't actually serve the purp=
ose of detecting value semantics - and that construction in general is alre=
ady a context where some things that look like copies/moves are not actuall=
y, I think we can get away with repurposing it, and gaining clarity and san=
ity in one of the most basic and important parts of the language: construct=
ing objects.
Maintaining sanity requires acknowledging subtle complexity.
It=E2=80=99s not too much to teach that 1) class value is the information t=
hat gets preserved by the lvalue-to-rvalue conversion, 2) as applied to the=
RHS of =3D, and 3) implemented by the copy and move constructors. This is =
not subtle; it should already be foundational knowledge. However, you can f=
airly substitute auto&& for auto as a fallback, and still call it AAA.
FWIW, to me, it=E2=80=99s a contortion to require that declarations should =
all begin with auto, and any resulting pain is deserved. If it hurts, stop =
doing it.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--Apple-Mail=_7A1D8298-3492-4F26-A630-25C39AA7AA37
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2015=E2=80=9309=
=E2=80=9312, at 9:48 AM, Mark A. Gibbs <<a href=3D"mailto:indi.in.the.wi=
red@gmail.com" class=3D"">indi.in.the.wired@gmail.com</a>> wrote:</div><=
br class=3D"Apple-interchange-newline"><div class=3D""><div dir=3D"ltr" cla=
ss=3D"">On Friday, 11 September 2015 04:11:43 UTC-4, David Krauss wrote:<b=
lockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;borde=
r-left: 1px #ccc solid;padding-left: 1ex;"><div style=3D"word-wrap:break-wo=
rd" class=3D""><div class=3D"">I didn=E2=80=99t say not to experiment, I sa=
id that you get into trouble when you lose value semantics. The problem wit=
h the example is that its =E2=80=9Cexperiment=E2=80=9D just seems to be a r=
andom jumble of keywords, and then you say that the result is surprising.</=
div></div></blockquote><div class=3D""><br class=3D"">That <i class=3D"">is=
</i> saying "don't experiment", because experimenting means trying things t=
hat you don't know whether they'll work or not, </div></div></div></blockqu=
ote><div><br class=3D""></div><div>How can you say whether something =E2=80=
=9Cworked=E2=80=9D if there was no goal in the first place? You only mentio=
ned "Wanting to explore constructors and destructors,=E2=80=9D so from that=
perspective, the experiment was a resounding success.</div><br class=3D"">=
<blockquote type=3D"cite" class=3D""><div class=3D""><div dir=3D"ltr" class=
=3D""><div class=3D"">and learning from the discovery of what happens. Okay=
, perhaps you're not saying "don't experiment <i class=3D"">ever</i>", but =
you <i class=3D"">are</i> saying "don't experiment with non-value types". O=
f course, the catch is that the beginner won't know that rule, and even if =
they do they won't know what non-value types are, so they won't know where =
they can or can't experiment. So, basically, "don't experiment=E2=80=9D.<br=
class=3D""></div></div></div></blockquote><div><br class=3D""></div><div>D=
on=E2=80=99t experiment unless you=E2=80=99re willing to discover something=
new. Don=E2=80=99t try to work in a vacuum, but maintain contact with the =
community of folks with related experience. These rules apply to all academ=
ia. Especially now, StackOverflow is always just a click away.</div><div><b=
r class=3D""></div><div>The confusion of the student in the second part of =
your example was due to copy elision, by the way, which isn=E2=80=99t guara=
nteed. Compilers still implement <font face=3D"Courier" class=3D"">-fno-eli=
de-copies</font> last I checked. Although in your example, elision can effe=
ctively be guaranteed because the initializer is a prvalue, in other cases =
the move constructor is still really used. To cover all the bases, you=E2=
=80=99d need to subdivide copy-initialization into more different cases. It=
would not ultimately be a simplification, you=E2=80=99d just be sweeping a=
few things further under the rug.</div><br class=3D""><blockquote type=3D"=
cite" class=3D""><div dir=3D"ltr" class=3D""><div class=3D"">Anyway, if it'=
s just that you think the experimentation example wasn't realistic, I can e=
asily provide you with a realistic one. I've seen it happen plenty of times=
..<br class=3D""></div></div></blockquote><div><br class=3D""></div><div>Sur=
e, fire away.</div><br class=3D""><blockquote type=3D"cite" class=3D""><div=
class=3D""><div dir=3D"ltr" class=3D""><blockquote class=3D"gmail_quote" s=
tyle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-le=
ft: 1ex;"><div style=3D"word-wrap:break-word" class=3D""><div class=3D"">An=
experiment is something that tests a hypothesis, and the example never sai=
d what the student was after.<br class=3D""></div></div></blockquote><div c=
lass=3D""><br class=3D"">Now you're just trying to be pedantic, but I can d=
o that, too. A <i class=3D"">science</i> experiment is one that involves hy=
pothesis testing, but even then not all science experiments involve hypothe=
ses: there is such a thing as "exploratory data analysis". Experimentation =
in the general sense is merely "trying shit to see what happens". The latte=
r type may be non-rigorous, but it is very often the first stage in an inve=
stigation that will be followed up by the former type. Great scientific dis=
coveries often start with "hm, I wonder what happens if=E2=80=A6".<br class=
=3D""></div></div></div></blockquote><div><br class=3D""></div><div>If the =
student is only trying to learn the rules, then they=E2=80=99re not allowed=
to be upset when they find one.</div><div><br class=3D""></div><div>I also=
recall learning about copy elision when copy constructor side effects disa=
ppeared. Even back then in the 90=E2=80=99s, there was literature to connec=
t the surprising result to class value semantics, and turn the =E2=80=9Cexp=
loratory data analysis=E2=80=9D into a valuable learning experience.</div><=
div><br class=3D""></div><div>Copy elision isn=E2=80=99t remotely new, nor =
is the element of surprise specific to non-value-semantic classes.</div><br=
class=3D""><blockquote type=3D"cite" class=3D""><div dir=3D"ltr" class=3D"=
"><div class=3D"">(Also, in the original example, there <i class=3D"">was</=
i> a hypothesis being tested. Specifically, that one of the four special me=
mber functions copy/move construct/assign was being used in that initializa=
tion statement. The experiment was putting markers in the four functions to=
reveal which. You could consider that a "closed testing procedure" that te=
sts multiple hypotheses - in this case, 4, each with its own null hypothesi=
s - simultaneously.)<br class=3D""></div></div></blockquote><div><br class=
=3D""></div><div>Another platform or another similar experiment would have =
resulted in the move constructor being called.</div><br class=3D""><blockqu=
ote type=3D"cite" class=3D""><div class=3D""><div dir=3D"ltr" class=3D""><b=
lockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;borde=
r-left: 1px #ccc solid;padding-left: 1ex;"><div style=3D"word-wrap:break-wo=
rd" class=3D""><div class=3D""><div class=3D"">In this case, the question w=
ould be, =E2=80=9Cwhy doesn=E2=80=99t the equals sign work=E2=80=9D?</div><=
/div></div></blockquote><div class=3D""><br class=3D"">Actually, the questi=
on is not "why doesn't the equal sign work", because "<span style=3D"font-f=
amily: courier new,monospace;" class=3D"">atomic<int> a =3D {};</span=
>" works but "<span style=3D"font-family: courier new,monospace;" class=3D"=
">atomic<int> a =3D atomic<int>{};</span>" doesn't. Clearly the=
equal sign does work. The question is why doesn't it work when I write the=
type twice, even though the braces on the right appear to be implying a de=
fault constructed atomic on the right</div></div></div></blockquote><div><b=
r class=3D""></div><div>False supposition.</div><br class=3D""><blockquote =
type=3D"cite" class=3D""><div class=3D""><div dir=3D"ltr" class=3D""><div c=
lass=3D""> that is being "put" in the atomic on the left - or aliased by th=
e variable being declared on the left. And this behaviour appears to be wha=
t that construct implies, because that's what apparently happens according =
to "<span style=3D"font-family: courier new,monospace;" class=3D"">atomic&l=
t;int> a =3D 0;</span>=E2=80=9D </div></div></div></blockquote><div><br =
class=3D""></div><div>I=E2=80=99ll grant that <font face=3D"Courier" class=
=3D"">atomic<int> a =3D 0</font> should work, but only because <font =
face=3D"Courier" class=3D"">0</font> is <i class=3D"">not</i> an <font=
face=3D"Courier" class=3D"">atomic</font>. If you use <font face=3D"Courie=
r" class=3D"">{0}</font>, there is no move (or elision) needed.</div><br cl=
ass=3D""><blockquote type=3D"cite" class=3D""><div class=3D""><div dir=3D"l=
tr" class=3D""><div class=3D"">(doesn't work because non-copy/non-movable) =
and "<span style=3D"font-family: courier new,monospace;" class=3D"">tuple&l=
t;int> t =3D {0};</span>" (doesn't work because construction on the righ=
t is implicit).<br class=3D""></div></div></div></blockquote><div><br class=
=3D""></div><div>This is already fixed.</div><br class=3D""><blockquote typ=
e=3D"cite" class=3D""><div class=3D""><div dir=3D"ltr" class=3D""><div clas=
s=3D"">I suggest that you are making a mistake by trying to interpret "<spa=
n style=3D"font-family: courier new,monospace;" class=3D"">type x =3D type{=
....};</span>" as an assignment between two values. Firstly, that seems a su=
spicious argument right from the get go, because you don't have two values.=
In fact, you have none before, then one after.</div></div></div></blockquo=
te><div><br class=3D""></div><div>The expression <font face=3D"Courier" cla=
ss=3D"">type{=E2=80=A6}</font>, like any expression, has a value. You want =
to use it as the initial value of a persistent object, but in the first pla=
ce it exists as a value, regardless of its enclosing context.</div><div><br=
class=3D""></div><div>Your model doesn=E2=80=99t seem to accommodate =
<font face=3D"Courier" class=3D"">type x =3D derived_type{};</font></div><b=
r class=3D""><blockquote type=3D"cite" class=3D""><div class=3D""><div dir=
=3D"ltr" class=3D""><div class=3D""> And unlike all other forms of initiali=
zation, in the interim you have two objects that were constructed out of wh=
ole cloth right there in the statement, unobservably (because of elision). =
(This is different from the cases of "<span style=3D"font-family: courier n=
ew,monospace;" class=3D"">type x =3D val;</span>" and "<span style=3D"font-=
family: courier new,monospace;" class=3D"">type x =3D func_yielding_rvalue(=
);</span>", because in both those two cases, the RHS value is constructed e=
lsewhere (though possibly elided).) The argument that you really, really wa=
nt this ghost object that never really exists seems weak.<br class=3D""><br=
class=3D"">Secondly, the language refutes that interpretation. If a non-co=
py/non-move type has a constructor that takes an int, but no assignment ope=
rators that take an int, this still works: "<span style=3D"font-family: cou=
rier new,monospace;" class=3D"">type x =3D {0};</span>=E2=80=9D.</div></div=
></div></blockquote><div><br class=3D""></div><div>What do assignment opera=
tors have to do with this?</div><br class=3D""><blockquote type=3D"cite" cl=
ass=3D""><div class=3D""><div dir=3D"ltr" class=3D""><div class=3D"">How ca=
n that be if this is actually a transfer of values? The type has no way to =
take an int (or an initializer list) except by construction, so it must the=
refore be constructing on the right... but that can't be, because the type =
is non-copy/non-movable, so if it were constructed on the right, it can't p=
ossibly be transferred to the left. </div></div></div></blockquote><div><br=
class=3D""></div><div>An <font face=3D"Courier" class=3D"">int</font> is c=
onstructed on the right and transferred to the left. Easy peasy.</div><br c=
lass=3D""><blockquote type=3D"cite" class=3D""><div dir=3D"ltr" class=3D"">=
<div class=3D"">Therefore there cannot be two values in that statement - th=
ere must only be one, the object on the right constructed with the int on t=
he left. (Of course, the language then turns around and screws you again, i=
f that constructor is explicit. As I keep saying, I think you're barking up=
the wrong tree trying to argue for consistency in construction statements.=
That ship has sailed.)<br class=3D""></div></div></blockquote><div><br cla=
ss=3D""></div><div>There=E2=80=99s plenty of literature on what <font face=
=3D"Courier" class=3D"">explicit</font> means, due to the recent <font face=
=3D"Courier" class=3D"">return</font> statement debate. Please review, for =
the sake of your students.</div><br class=3D""><blockquote type=3D"cite" cl=
ass=3D""><div dir=3D"ltr" class=3D""><blockquote class=3D"gmail_quote" styl=
e=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left:=
1ex;"><div style=3D"word-wrap:break-word" class=3D""><div class=3D""><div =
class=3D"">And the answer would be, =E2=80=9Cthe right-hand side doesn=E2=
=80=99t behave as a value.=E2=80=9D</div></div></div></blockquote><div clas=
s=3D""> <br class=3D"">Yet this works:<br class=3D""><div class=3D"pre=
ttyprint" style=3D"background-color: rgb(250, 250, 250); border-color: rgb(=
187, 187, 187); border-style: solid; border-width: 1px; word-wrap: break-wo=
rd;"><code class=3D"prettyprint"><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">auto</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">&&</span> x <span style=3D"color: #660;" class=3D"styled-=
by-prettify">=3D</span> std<span style=3D"color: #660;" class=3D"styled-by-=
prettify">::</span>atomic<span style=3D"color: #080;" class=3D"styled-by-pr=
ettify"><int></span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">{};</span></code></div><br class=3D"">So clearly the claim that "=
=3D" only works with value types just doesn't hold water.<br class=3D""><br=
class=3D"">"=3D" may be the dividing line between value types and non-valu=
e types in general code - when it is actually being used as an assignment. =
But in the context of initialization, it isn't, at least not consistently.<=
br class=3D""></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div style=
=3D"word-wrap:break-word" class=3D""><div class=3D""></div></div></blockquo=
te></div></blockquote><div><br class=3D""></div><div>This is temporary life=
time extension. Is it impure to use <font face=3D"Courier" class=3D"">=
=3D</font> for reference binding? Interesting thought. However, the ea=
sy answer is that the value on the RHS is exactly preserved by reference bi=
nding, overriding class semantics. All expressions have values, after all, =
and =E2=80=9Cnon-value-semantic=E2=80=9D classes are only ones which may mi=
sbehave when some mathematical abstraction is assumed. =E2=80=9CValue seman=
tic=E2=80=9D refers to the notion of separating a value from an object, not=
the existence of a value in the first place.</div><div><br class=3D""></di=
v><div>Reference binding gives expression templates conniptions: They use n=
on-value types to represent mathematical values.</div><div><br class=3D""><=
/div><div>A reference stores an lvalue, i.e. an alias to an object which mu=
st remain valid =E2=80=94 I=E2=80=99m content to leave it at that. (Well, n=
ot exactly satisfied=E2=80=A6 the language should do more validation, and u=
ser-defined types should have access to lifetime extension as well, hence m=
y proposal <a href=3D"http://bit.ly/genlife" class=3D"">bit.ly/genlife</a>.=
)</div><div><br class=3D""></div><blockquote type=3D"cite" class=3D""><div =
dir=3D"ltr" class=3D""><blockquote class=3D"gmail_quote" style=3D"margin: 0=
;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div st=
yle=3D"word-wrap:break-word" class=3D""><div class=3D""><div class=3D"">The=
flip side of regular syntax with loose semantic constraints is getting une=
xpected meaning from templates. Some things aren=E2=80=99t <i class=3D"">su=
pposed</i> to compile.</div></div></div></blockquote><div class=3D""><=
br class=3D"">But as I pointed out, that argument doesn't really apply to d=
eclarations of the form "<span style=3D"font-family: courier new,monospace;=
" class=3D"">type x =3D type{...};</span>". <i class=3D"">Nobody</i> writes=
code like that with the expectation that it is the only thing keeping non-=
copy/non-move types out the door. Almost 20 years of C++ and 10 years of te=
aching it, </div></div></blockquote><div><br class=3D""></div><div>Nobody i=
n their right mind would write <font face=3D"Courier" class=3D"">type</font=
> on both sides of the equals sign before C++11. We=E2=80=99re both limited=
to 4-5 years experience with this.</div><br class=3D""><blockquote type=3D=
"cite" class=3D""><div dir=3D"ltr" class=3D""><div class=3D"">I have never =
seen that done (and I've seen some crazy shit). Anybody who does that is be=
ing "clever" to the point of frustrating future maintenance of the code, so=
there is no reason the standard should have to bless that behaviour. There=
are better ways to prevent generic code from compiling in the face of a no=
n-value type. We just don't need this particular case.<br class=3D""><br cl=
ass=3D"">Also, I'm not proposing "loose" semantic constraints. I'm proposin=
g very rigorous constraints... just constraints that are different from the=
existing ones in one specific context (which are specious).<br class=3D"">=
</div></div></blockquote><div><br class=3D""></div><div>To me, you sound sp=
ecious. But I=E2=80=99m keeping an open mind; you=E2=80=99re the one pacing=
this discussion.</div><br class=3D""><blockquote type=3D"cite" class=3D"">=
<div dir=3D"ltr" class=3D""><div class=3D"">You're making it sound like I'm=
proposing throwing all distinction between value and non-value types out -=
or perhaps removing the ability for "=3D" to distinguish in all cases. Tha=
t's not so. I'm talking about taking one... specific... instance - just "<s=
pan style=3D"font-family: courier new,monospace;" class=3D"">type x =3D typ=
e{...};</span>", and not even "<span style=3D"font-family: courier new,mono=
space;" class=3D"">type x =3D val;</span>" or "<span style=3D"font-family: =
courier new,monospace;" class=3D"">type x =3D func();</span>", those should=
still fail in the absence of copy/move ops - in a context where there are =
already lots of special cases and exceptions (initialization), and for the =
gain of ending the madness of having no way to construct a new object that =
works for all types. I think we can let this one go.<br class=3D""></div><b=
lockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;borde=
r-left: 1px #ccc solid;padding-left: 1ex;"><div style=3D"word-wrap:break-wo=
rd" class=3D""></div></blockquote></div></blockquote><div><br class=3D""></=
div><div>What about <font face=3D"Courier" class=3D"">type x =3D type{ func=
() }</font>?</div><br class=3D""><blockquote type=3D"cite" class=3D""><div =
dir=3D"ltr" class=3D""><blockquote class=3D"gmail_quote" style=3D"margin: 0=
;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div st=
yle=3D"word-wrap:break-word" class=3D""><div class=3D"">There=E2=80=99s a l=
anguage for that: Java. (Except, scalars in Java are new objects without us=
ing the <font face=3D"Courier" class=3D"">new</font> keyword.)</div></div><=
/blockquote><div class=3D""><br class=3D"">I realize you're invoking Java a=
s the exemplar of a language that prefers simplicity and consistency at the=
expense of flexibility, expressiveness and power... exactly what we don't =
want C++ to become. But frankly, if a bad language has a good idea... I'm a=
-gonna take it. I don't care if the rest of the design in that language is =
misguided - if it has something that works well, and it can be done in C++ =
without sacrificing anything important... yeah, I'll steal from Java. I don=
't have so much pride that I would refuse a good idea just because of its s=
ource.<br class=3D""></div><blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"></b=
lockquote></div></blockquote><div><br class=3D""></div><div>Just as there=
=E2=80=99s C++-as-C, there=E2=80=99s also C++-as-Java =E2=80=94 albeit with=
no garbage collector. (We <i class=3D"">should</i> have a GC alr=
eady, though!) Many instructors have really gone that route, to the chagrin=
of the rest of the community.</div><br class=3D""><blockquote type=3D"cite=
" class=3D""><div dir=3D"ltr" class=3D""><div class=3D"">I didn't claim the=
y were equivalent. In fact, I obviously realize they aren't because the who=
le point of my proposal is to <i class=3D"">make</i> them equivalent.<br cl=
ass=3D""><br class=3D"">I pointed out that the claim that "=3D" implies val=
ue semantics is false. Atomics don't have value semantics, yet you can do "=
<span style=3D"font-family: courier new,monospace;" class=3D"">atomic<in=
t> a =3D {};</span>=E2=80=9D.<br class=3D""></div></div></blockquote><di=
v><br class=3D""></div><div>Hmm, you deleted the part where I explained tha=
t is equivalent to <font face=3D"Courier" class=3D"">atomic<int> a =
=3D {0};</font> and then re-asked the question.</div><div><br class=3D""></=
div><div><font face=3D"Courier" class=3D"">A: atomic<int> a =3D {};</=
font></div><div><div><font face=3D"Courier" class=3D"">B: atomic<int>=
a =3D {0};</font></div><div class=3D""><div><font face=3D"Courier" class=
=3D"">C: atomic<int> a =3D atomic<int>{};</font></div></div><di=
v class=3D""><font face=3D"Courier" class=3D""><br class=3D""></font></div>=
</div><div>A is equivalent to B. Not by language semantics, but because the=
class defines it that way.</div><div>A is not equivalent to C. You propose=
to make them equivalent at the language level.</div><div><br class=3D""></=
div><div>What about classes for which B is not equivalent to C?</div><br cl=
ass=3D""><blockquote type=3D"cite" class=3D""><div class=3D""><div dir=3D"l=
tr" class=3D""><div class=3D"">If it were really true that "=3D" really did=
imply value semantics in all cases, then I would have to acquiesce - you w=
ould be right, and maintaining a clear wall distinction between value types=
and non-value types is more important than convenience. But it doesn't alw=
ays imply value semantics. There are already exceptions and gotchas... <i c=
lass=3D"">especially</i> in the context I'm focused on. Since the wall is a=
lready full of holes, the argument for adding one more that makes things re=
ally convenient and consistent suddenly has merit.<br class=3D""> </di=
v><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;b=
order-left: 1px #ccc solid;padding-left: 1ex;"><div style=3D"word-wrap:brea=
k-word" class=3D"">Arguably this should work too:<div class=3D""><br class=
=3D""></div><div class=3D""><div class=3D""><font face=3D"Courier" class=3D=
"">atomic< int > x =3D 0;</font></div><div class=3D""><br class=3D"">=
</div><div class=3D"">I do think it=E2=80=99s a bit silly to convert to a t=
emporary before initializing the named variable, but I can=E2=80=99t commen=
t further without digging into the history of the language.</div></div></di=
v></blockquote><div class=3D""><br class=3D"">So why shouldn't this?:<br cl=
ass=3D""><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250=
, 250); border-color: rgb(187, 187, 187); border-style: solid; border-width=
: 1px; word-wrap: break-word;"><code class=3D"prettyprint">atomic<span styl=
e=3D"color: #080;" class=3D"styled-by-prettify"><int></span> a <span =
style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span> atomic<span =
style=3D"color: #080;" class=3D"styled-by-prettify"><int></span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D=
"color: #066;" class=3D"styled-by-prettify">0</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">};</span></code></div><br class=3D"">Wha=
t you're saying is that you think that it's reasonable that "<span style=3D=
"font-family: courier new,monospace;" class=3D"">atomic<int> a =3D 0;=
</span>" should be interpreted as "<span style=3D"font-family: courier new,=
monospace;" class=3D"">atomic<int> a{0};</span>=E2=80=9D</div></div><=
/div></blockquote><div><br class=3D""></div><div>No, I=E2=80=99m saying it=
=E2=80=99s reasonable to interpret it as <font face=3D"Courier" class=3D"">=
atomic<int> a =3D {0}</font> with braces <i class=3D"">and</i> t=
he equals sign.</div><br class=3D""><blockquote type=3D"cite" class=3D""><d=
iv class=3D""><div dir=3D"ltr" class=3D""><div class=3D"">, and not "<span =
style=3D"font-family: courier new,monospace;" class=3D"">atomic<int> =
a =3D atomic<int>{0};</span>" (as it currently is). I agree - I see n=
o sane reason why it shouldn't. It's obvious what you really mean, and ther=
e's really no reason a temporary has to be constructed then transferred to =
the named variable.<br class=3D""><br class=3D"">So if that's reasonable, w=
hy is interpreting "<span style=3D"font-family: courier new,monospace;" cla=
ss=3D"">atomic<int> a =3D atomic<int>{0};</span>" as "<span sty=
le=3D"font-family: courier new,monospace;" class=3D"">atomic<int> a{0=
};</span>" so crazy? It's the exact... same... reasoning: It's obvious what=
you really mean, and there's really no reason a temporary has to be constr=
ucted then transferred to the named variable.<br class=3D""></div></div></d=
iv></blockquote><div><br class=3D""></div><div>No, because it should be pos=
sible to substitute a function, even returning a derived type, on the RHS.<=
/div><br class=3D""><blockquote type=3D"cite" class=3D""><div class=3D""><d=
iv dir=3D"ltr" class=3D""><div class=3D"">Remember, "<span style=3D"font-fa=
mily: courier new,monospace;" class=3D"">atomic<int> a =3D {0};</span=
>" is already interpreted as "<span style=3D"font-family: courier new,monos=
pace;" class=3D"">atomic<int> a{0};</span>=E2=80=9D.</div></div></div=
></blockquote><div><br class=3D""></div><div>Not at the language level; tho=
se behave differently given an <font face=3D"Courier" class=3D"">expli=
cit</font> constructor.</div><br class=3D""><blockquote type=3D"cite" class=
=3D""><div class=3D""><div dir=3D"ltr" class=3D""><div class=3D""> "<span s=
tyle=3D"font-family: courier new,monospace;" class=3D"">{0}</span>" just by=
itself is an <span style=3D"font-family: courier new,monospace;" class=3D"=
">initializer_list<int></span>, </div></div></div></blockquote><div><=
br class=3D""></div><div>Not by a long shot.</div><br class=3D""><blockquot=
e type=3D"cite" class=3D""><div class=3D""><div dir=3D"ltr" class=3D""><div=
class=3D"">yet <span style=3D"font-family: courier new,monospace;" class=
=3D"">atomic<int></span> has no <span style=3D"font-family: courier n=
ew,monospace;" class=3D"">initializer_list<int></span> constructor, s=
o that has to be what the interpretation of what's happening is - the "<spa=
n style=3D"font-family: courier new,monospace;" class=3D"">{0}</span>" is n=
ot "an initializer list", but rather "the initializer list for the atomic b=
eing constructed". This is already a context were the "normal" rules of "=
=3D" just don't apply. </div></div></div></blockquote><div><br class=3D""><=
/div><div>The normal rule of <font face=3D"Courier" class=3D"">=3D</font> i=
s lvalue-to-rvalue conversion on the RHS. As far as I know, pre-conversion =
to a temporary of the initialized type is a mere historical artifact. It wo=
uld be interesting to see a well-researched proposal to regularize <font fa=
ce=3D"Courier" class=3D"">=3D x</font> initializers with <font face=3D"Cour=
ier" class=3D"">=3D {x}</font>. I=E2=80=99m sure the guys who drafted the c=
opy-list-initialization spec thought about the difference, and such researc=
h should not overlook the generalized initializer list proposals, which are=
numerous and deep.</div><br class=3D""><blockquote type=3D"cite" class=3D"=
"><div class=3D""><div dir=3D"ltr" class=3D""><div class=3D"">What I'm prop=
osing is basically just interpreting "<span style=3D"font-family: courier n=
ew,monospace;" class=3D"">atomic<int> a =3D atomic<int>{0};</sp=
an>" as "<span style=3D"font-family: courier new,monospace;" class=3D"">ato=
mic<int> a atomic<int>{0};</span>", then dropping the redundant=
repetition of the type. (But, of course, ONLY in the case where the type a=
ctually is repeated.)<br class=3D""> </div><blockquote class=3D"gmail_=
quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;pa=
dding-left: 1ex;"><div style=3D"word-wrap:break-word" class=3D""><div class=
=3D"">True, you=E2=80=99re proposing to guarantee elision of that copy. But=
copy elision was never intended as a pillar of the language. Things are su=
pposed to work without it; it=E2=80=99s not a failsafe bypass around the lv=
alue-to-rvalue conversion.</div></div></blockquote><div class=3D""> <b=
r class=3D"">Yes, and I am proposing to change that - in this one, specific=
syntactic construct. That's why elision is mentioned in the topic.<br clas=
s=3D""></div></div></div></blockquote><div><br class=3D""></div><div>Applyi=
ng it for class conversion expressions but not function calls: is that real=
ly going to improve teachability? Much less real-life usability?</div><div>=
<br class=3D""></div><div>Maybe it=E2=80=99s time to recognize the =E2=80=
=9Calmost=E2=80=9D in AAA.</div><br class=3D""><blockquote type=3D"cite" cl=
ass=3D""><div class=3D""><div dir=3D"ltr" class=3D""><div class=3D"">You're=
right, the current state of affairs is that elision is optional in all cas=
es, even in the case that I'm focused on. My argument is if we change that =
rule just in this specific case, to make the elision effectively required -=
and "required" to the point that there is no moving at all, even conceptua=
lly - we gain:<br class=3D""><ul class=3D""><li class=3D"">guaranteed effic=
iency (as opposed to almost-certain but not required efficiency)</li><li cl=
ass=3D"">and a practical solution to the initialization madness that works =
in all cases (though may not do precisely what you specifically need in a s=
pecific case, in which case you still have the other options).<br class=3D"=
"></li></ul>The only purposes behind keeping the requirement that the type =
be copy/movable are either a) to maintain language purity wrt the distincti=
on of value/non-value types, or b) because it is a practical way to actuall=
y distinguish between value/non-value types in generic code.<br class=3D"">=
<br class=3D"">For (a), I say that goal is already a lost cause, in this co=
ntext. There are so many peculiarities in the interpretations of the variou=
s construction syntaxes, that this doesn't really seem the right place to b=
e adamant about drawing this line.<br class=3D""></div></div></div></blockq=
uote><div><br class=3D""></div><div>You seem to be implicitly admitting tha=
t others have a broader perspective than yourself, but that you=E2=80=99re =
not willing to see the forest for the trees.</div><div><br class=3D""></div=
><div>There=E2=80=99s no particular reason to expect AAA to work genericall=
y. It=E2=80=99s a recent invention since C++11, unrelated to earlier practi=
ce. Maybe a language can be designed around it, but a comprehensive retrofi=
t to C++ is unlikely.</div><div><br class=3D""></div><div>That said, given =
my accessor lifetime extension proposal and another one (not updated for Ko=
na, but not dead) N4149 regarding expression template conversions, you coul=
d do</div><div><br class=3D""></div><div><font face=3D"Courier" class=3D"">=
auto guard =3D make_guard();</font></div><div><br class=3D""></div><div>whe=
rein the =E2=80=9Cvalue=E2=80=9D of a guard cannot be moved to a new object=
, but it can generate an accessor view to itself, leading to its self-prese=
rvation.</div><br class=3D""><blockquote type=3D"cite" class=3D""><div clas=
s=3D""><div dir=3D"ltr" class=3D""><div class=3D"">For (b), I say: nobody d=
oes it for that purpose, nobody would understand that's what the intention =
was if it was actually used for that purpose, there are several other - bet=
ter - ways of achieving the same goal, and finally, it just don't work anyw=
ay. There are more requirements to having value semantics than just being c=
opy/movable, so a type that does not have value semantics but is copy/movab=
le would pass the bar.<br class=3D""></div></div></div></blockquote><div><b=
r class=3D""></div><div>Value vs. non-value isn=E2=80=99t black and white. =
Not sure exactly what goal you=E2=80=99re supposing.</div><div><br class=3D=
""></div><div>To be sure, a template over numeric types should not accept <=
font face=3D"Courier" class=3D"">atomic<int></font>. It=E2=80=99s a f=
acility for managing integers safely against multithreaded aliasing. It can=
store and retrieve an integer value, even up to implicitly converting both=
ways, but that doesn=E2=80=99t actually make it a number.</div><div><br cl=
ass=3D""></div><div>Sure, it takes time to teach that to a student. But I t=
hink that=E2=80=99s time well spent.</div><br class=3D""><blockquote type=
=3D"cite" class=3D""><div class=3D""><div dir=3D"ltr" class=3D""><div class=
=3D"">Given that the syntax doesn't actually distinguish anything but wheth=
er the type is non-copy/non-movable or not - it doesn't actually serve the =
purpose of detecting value semantics - and that construction in general is =
already a context where some things that look like copies/moves are not act=
ually, I think we can get away with repurposing it, and gaining clarity and=
sanity in one of the most basic and important parts of the language: const=
ructing objects.<br class=3D""></div></div></div></blockquote><br class=3D"=
"></div><div>Maintaining sanity requires acknowledging subtle complexity.</=
div><div><br class=3D""></div><div>It=E2=80=99s not too much to teach that =
1) class value is the information that gets preserved by the lvalue-to-rval=
ue conversion, 2) as applied to the RHS of <font face=3D"Courier" class=3D"=
">=3D</font>, and 3) implemented by the copy and move constructors. This is=
<i class=3D"">not</i> subtle; it should already be foundational knowl=
edge. However, you can fairly substitute <font face=3D"Courier" class=3D"">=
auto&&</font> for <font face=3D"Courier" class=3D"">auto</font> as =
a fallback, and still call it AAA.</div><br class=3D""><div class=3D"">FWIW=
, to me, it=E2=80=99s a contortion to require that declarations should all =
begin with <font face=3D"Courier" class=3D"">auto</font>, and any resulting=
pain is deserved. If it hurts, stop doing it.</div><div class=3D""><br cla=
ss=3D""></div></body></html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--Apple-Mail=_7A1D8298-3492-4F26-A630-25C39AA7AA37--
.
Author: Tomasz <tomaszkam@gmail.com>
Date: Sat, 12 Sep 2015 01:43:43 -0700 (PDT)
Raw View
------=_Part_1644_1405812434.1442047423493
Content-Type: multipart/alternative;
boundary="----=_Part_1645_1047729748.1442047423494"
------=_Part_1645_1047729748.1442047423494
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
W dniu sobota, 12 wrze=C5=9Bnia 2015 02:20:03 UTC+2 u=C5=BCytkownik Mark A.=
Gibbs=20
napisa=C5=82:
>
>
>
> No initialization syntax is perfect. But the difference between your=20
> example and mine is that mine is a plausible update to a code base to=20
> accommodate growth, whereas yours is really just a really dumb refactorin=
g=20
> decision that someone hoped that compiler would spare them from the=20
> consequences of. The "auto" version catches the plausible modification,=
=20
> but misses the terrible refactoring job. The non-"auto" version catches=
=20
> the really dumb change that should never happen, but fails to catch the=
=20
> plausible modification. Frankly, I'd prefer the "auto" result, in=20
> practice. Oh, also, the "auto" version will crash the very first time the=
=20
> code that puts the result of createDerived() in a unique_ptr gets called=
=20
> - basically day 1 of testing - and debug mode will give you a message abo=
ut=20
> the double-delete... meanwhile the bug in the non-"auto" version could go=
=20
> for years without being detected, unless and and until there happens to b=
e=20
> a case when the result of get_count() is too large, which may only happen=
=20
> sporadically and be hard to reproduce. Advantage: auto.
>
> The same advantage applies for int x{get_count()} and this advantage=20
applies only for the build-in arithmetic types that allows numeric=20
conversion. =20
Back to your example, relying on the semantics of "type x =3D=20
> factory_function();" is a bad idea. Unless you put a comment next to it=
=20
> explicitly explaining that that's what you intend, you risk someone comin=
g=20
> along and thinking that "type x{factory_function()};" is a better idea,=
=20
> because it prevents narrowing, or something similar. The smart thing to d=
o=20
> is this:
>
Again, such refactoring only give a gains for a small set of types, i.e.=20
built in arithmetic types, that allows narrowing conversion. The type x =3D=
=20
factory_function() prevents explicit conversion for every other type. That=
=20
is way I do not like pomotion of auto x =3D type{expr} syntax - the gain is=
=20
achieved for very small set of types, versus possible safety loss of others=
..
=20
> template <typename T, typename U>
> auto as(U&& u) -> T
> {
> return {u};
> }
>
> auto s =3D as<std::chrono::seconds>(get_timeout());
> // or if you prefer a different name:
> auto s =3D implicitly_as<std::chrono::seconds>(get_timeout());
> auto s =3D safely_as<std::chrono::seconds>(get_timeout());
>
> That will catch unwanted explicit conversions... and it will catch=20
> narrowing (and if you don't want that, drop the braces)... *and* it is=20
> self-documenting in code. And if you don't use the auto there, you have=
=20
> to repeat the type, which is a bad idea. For auto, I think that's game,=
=20
> set, and match.
>
The new C++ cast was designed, they was intended to be long and ugly, to=20
give a visible hint that something may be wrong. You are currently=20
proposing that:
auto s =3D type{expr};
Syntax should be used for unsafe conversions. And:
auto s =3D as<std::chrono::seconds>(get_timeout());
auto s =3D implicitly_as<std::chrono::seconds>(get_timeout());
auto s =3D safely_as<std::chrono::seconds>(get_timeout());
For the one that was marked as safe by author of the class.
=20
>
> Perhaps those of us who want to "force" everyone to use the "shiny new=20
> auto" have given this a bit more thought than you give us credit for.
>
> Anyway, to be clear, I am not proposing a way to initialize objects that=
=20
> will solve every single possible problem imaginable. I am just proposing =
a=20
> way that will work for every type, and do a sensible thing in all cases. =
It=20
> may not work precisely the way you need it to for your specific instance,=
=20
> in which case you can use a more specific form.
>
I do not think that invoking conversion that was marked as unsafe by the=20
class author (marked explicit) is sensible default. And the avoidance of=20
narrowing conversion for small set of types, does not justify it.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_1645_1047729748.1442047423494
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<br>W dniu sobota, 12 wrze=C5=9Bnia 2015 02:20:03 UTC+2 u=C5=BCytkownik Mar=
k A. Gibbs napisa=C5=82:<blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div d=
ir=3D"ltr"><br><div><br>No initialization syntax is perfect. But the differ=
ence between your example and mine is that mine is a plausible update to a =
code base to accommodate growth, whereas yours is really just a really dumb=
refactoring decision that someone hoped that compiler would spare them fro=
m the consequences of. The "<span style=3D"font-family:courier new,mon=
ospace">auto</span>" version catches the plausible modification, but m=
isses the terrible refactoring job. The non-"<span style=3D"font-famil=
y:courier new,monospace">auto</span>" version catches the really dumb =
change that should never happen, but fails to catch the plausible modificat=
ion. Frankly, I'd prefer the "<span style=3D"font-family:courier n=
ew,monospace">auto</span>" result, in practice. Oh, also, the "<s=
pan style=3D"font-family:courier new,monospace">auto</span>" version w=
ill crash the very first time the code that puts the result of <span style=
=3D"font-family:courier new,monospace">createDerived()</span> in a <span st=
yle=3D"font-family:courier new,monospace">unique_ptr</span> gets called - b=
asically day 1 of testing - and debug mode will give you a message about th=
e double-delete... meanwhile the bug in the non-"<span style=3D"font-f=
amily:courier new,monospace">auto</span>" version could go for years w=
ithout being detected, unless and and until there happens to be a case when=
the result of <span style=3D"font-family:courier new,monospace">get_count(=
)</span> is too large, which may only happen sporadically and be hard to re=
produce. Advantage: <span style=3D"font-family:courier new,monospace">auto<=
/span>.<br><br></div></div></blockquote><div>The same advantage applies for=
<span style=3D"font-family: courier new,monospace;">int x{get_count()}<fon=
t face=3D"arial,sans-serif"> and this advantage applies only for the build-=
in arithmetic types that allows numeric conversion.=C2=A0</font></span> </d=
iv><div><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"=
ltr"><div>Back to your example, relying on the semantics of "<span sty=
le=3D"font-family:courier new,monospace">type x =3D factory_function();</sp=
an>" is a bad idea. Unless you put a comment next to it explicitly exp=
laining that that's what you intend, you risk someone coming along and =
thinking that "<span style=3D"font-family:courier new,monospace">type =
x{factory_function()};</span>" is a better idea, because it prevents n=
arrowing, or something similar. The smart thing to do is this:<br></div></d=
iv></blockquote><div><br>Again, such refactoring only give a gains for a sm=
all set of types, i.e. built in arithmetic types, that allows narrowing con=
version. The type x =3D factory_function() prevents explicit conversion for=
every other type. That is way I do not like pomotion of auto x =3D type{ex=
pr} syntax - the gain is achieved for very small set of types, versus possi=
ble safety loss of others.<br><br>=C2=A0</div><blockquote class=3D"gmail_qu=
ote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padd=
ing-left: 1ex;"><div dir=3D"ltr"><div><div style=3D"background-color:rgb(25=
0,250,250);border-color:rgb(187,187,187);border-style:solid;border-width:1p=
x;word-wrap:break-word"><code><div><span style=3D"color:#008">template</spa=
n><span style=3D"color:#000"> </span><span style=3D"color:#660"><</span>=
<span style=3D"color:#008">typename</span><span style=3D"color:#000"> T</sp=
an><span style=3D"color:#660">,</span><span style=3D"color:#000"> </span><s=
pan style=3D"color:#008">typename</span><span style=3D"color:#000"> U</span=
><span style=3D"color:#660">></span><span style=3D"color:#000"><br></spa=
n><span style=3D"color:#008">auto</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#008">as</span><span style=3D"color:#660">(</span><spa=
n style=3D"color:#000">U</span><span style=3D"color:#660">&&</span>=
<span style=3D"color:#000"> u</span><span style=3D"color:#660">)</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#660">-></span><span=
style=3D"color:#000"> T<br></span><span style=3D"color:#660">{</span><span=
style=3D"color:#000"><br>=C2=A0 </span><span style=3D"color:#008">return</=
span><span style=3D"color:#000"> </span><span style=3D"color:#660">{</span>=
<span style=3D"color:#000">u</span><span style=3D"color:#660">};</span><spa=
n style=3D"color:#000"><br></span><span style=3D"color:#660">}</span><span =
style=3D"color:#000"><br><br></span><span style=3D"color:#008">auto</span><=
span style=3D"color:#000"> s </span><span style=3D"color:#660">=3D</span><s=
pan style=3D"color:#000"> </span><span style=3D"color:#008">as</span><span =
style=3D"color:#660"><</span><span style=3D"color:#000">std</span><span =
style=3D"color:#660">::</span><span style=3D"color:#000">chrono</span><span=
style=3D"color:#660">::</span><span style=3D"color:#000">seconds</span><sp=
an style=3D"color:#660">>(</span><span style=3D"color:#000">get_<wbr>tim=
eout</span><span style=3D"color:#660">());</span><span style=3D"color:#000"=
><br></span><span style=3D"color:#800">// or if you prefer a different name=
:</span><span style=3D"color:#000"><br></span><span style=3D"color:#008">au=
to</span><span style=3D"color:#000"> s </span><span style=3D"color:#660">=
=3D</span><span style=3D"color:#000"> implicitly_as</span><span style=3D"co=
lor:#660"><</span><span style=3D"color:#000">std</span><span style=3D"co=
lor:#660">::</span><span style=3D"color:#000">chrono</span><span style=3D"c=
olor:#660">::</span><span style=3D"color:#000">sec<wbr>onds</span><span sty=
le=3D"color:#660">>(</span><span style=3D"color:#000">get_timeout</span>=
<span style=3D"color:#660">());</span><span style=3D"color:#000"><br></span=
><span style=3D"color:#008">auto</span><span style=3D"color:#000"> s </span=
><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> safely_as=
</span><span style=3D"color:#660"><</span><span style=3D"color:#000">std=
</span><span style=3D"color:#660">::</span><span style=3D"color:#000">chron=
o</span><span style=3D"color:#660">::</span><span style=3D"color:#000">seco=
nds</span><span style=3D"color:#660"><wbr>>(</span><span style=3D"color:=
#000">get_timeout</span><span style=3D"color:#660">());</span></div></code>=
</div><br>That will catch unwanted explicit conversions... and it will catc=
h narrowing (and if you don't want that, drop the braces)... <i>and</i>=
it is self-documenting in code. And if you don't use the <span style=
=3D"font-family:courier new,monospace">auto</span> there, you have to repea=
t the type, which is a bad idea. For <span style=3D"font-family:courier new=
,monospace">auto</span>, I think that's game, set, and match.<br></div>=
</div></blockquote><div><br>The new C++ cast was designed, they was intende=
d to be long and ugly, to give a visible hint that something may be wrong. =
You are currently proposing that:<br>auto s =3D type{expr};<br><font size=
=3D"2"><span style=3D"font-family: arial,sans-serif;">Syntax should be used=
for unsafe conversions. And:<br><code></code></span></font>auto s =3D as&l=
t;std::chrono::seconds>(get_timeout());<br>auto s =3D implicitly_as<s=
td::chrono::seconds>(get_timeout());<br>auto s =3D safely_as<std::chr=
ono::seconds>(get_timeout());<br>For the one that was marked as safe by =
author of the class.<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><div dir=3D"ltr"><div><br>Perhaps those of us who want to "force=
" everyone to use the "shiny new <span style=3D"font-family:couri=
er new,monospace">auto</span>" have given this a bit more thought than=
you give us credit for.<br><br>Anyway, to be clear, I am not proposing a w=
ay to initialize objects that will solve every single possible problem imag=
inable. I am just proposing a way that will work for every type, and do a s=
ensible thing in all cases. It may not work precisely the way you need it t=
o for your specific instance, in which case you can use a more specific for=
m.<br></div></div></blockquote><div><br>I do not think that invoking conver=
sion that was marked as unsafe by the class author (marked explicit) is sen=
sible default. And the avoidance of narrowing conversion for small set of t=
ypes, does not justify it.<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_1645_1047729748.1442047423494--
------=_Part_1644_1405812434.1442047423493--
.
Author: Markus Grech <markus.grech@gmail.com>
Date: Sat, 12 Sep 2015 07:19:53 -0700 (PDT)
Raw View
------=_Part_1813_1971933179.1442067593802
Content-Type: multipart/alternative;
boundary="----=_Part_1814_2125963893.1442067593802"
------=_Part_1814_2125963893.1442067593802
Content-Type: text/plain; charset=UTF-8
Uniform initialization was one of the biggest mistakes in the language to
date. I can therefore only agree with the idea to fix this issue to provide
a true uniform syntax. Please do not forget arrays however, something like
the following should work as well:
auto x = int[]{ 1, 2, 3 };
Not sure if this is doable without ambiguities.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_1814_2125963893.1442067593802
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Uniform initialization was one of the biggest mistakes in =
the language to date. I can therefore only agree with the idea to fix this =
issue to provide a true uniform syntax. Please do not forget arrays however=
, something like the following should work as well:<div><div class=3D"prett=
yprint" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-wor=
d; background-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><div =
class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> x </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</=
span><font color=3D"#000088"><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">int</span><span style=3D"color: #660;" class=3D"styled-by-prettify">[]{<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #066;" class=3D"styled-by-prettify">1</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #066;" =
class=3D"styled-by-prettify">2</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #066;" class=3D"styled-by-prettify=
">3</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">};</span></font>=
</div></code></div>Not sure if this is doable without ambiguities.</div></d=
iv>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_1814_2125963893.1442067593802--
------=_Part_1813_1971933179.1442067593802--
.
Author: Martin Molzer <martin.molzer@gmx.de>
Date: Sat, 23 Jan 2016 18:13:47 -0800 (PST)
Raw View
------=_Part_227_1564310763.1453601627634
Content-Type: multipart/alternative;
boundary="----=_Part_228_1882891254.1453601627634"
------=_Part_228_1882891254.1453601627634
Content-Type: text/plain; charset=UTF-8
Just want to post a question I asked on stackoverflow where a comment was
that my code wasn't future proof. It was about a class that could not be
created on the heap, relying on a deleted copy and move constructor and the
fact that you can capture such a variable in a temporary:
http://stackoverflow.com/questions/34948403/
This proposal would destroy that use case, if it'd go through and actually
open up a problem for me if there was no way to suppress the behaviour for
a specific class.
I have no proposition on how to tell the compiler that a specific class
would not allow copy/move elision but if it would, to be consistent, I'd
make it forbidden to do so, even in the cases that are currently allowed by
the standard. But there should be a way to forbid/restrict - see
private/protected move and copy constructors.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_228_1882891254.1453601627634
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Just want to post a question I asked on stackoverflow wher=
e a comment was that my code wasn't future proof. It was about a class =
that could not be created on the heap, relying on a deleted copy and move c=
onstructor and the fact that you can capture such a variable in a temporary=
:<br><br>http://stackoverflow.com/questions/34948403/<br><br>This proposal =
would destroy that use case, if it'd go through and actually open up a =
problem for me if there was no way to suppress the behaviour for a specific=
class.<br><br>I have no proposition on how to tell the compiler that a spe=
cific class would not allow copy/move elision but if it would, to be consis=
tent, I'd make it forbidden to do so, even in the cases that are curren=
tly allowed by the standard. But there should be a way to forbid/restrict -=
see private/protected move and copy constructors.<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_228_1882891254.1453601627634--
------=_Part_227_1564310763.1453601627634--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sun, 24 Jan 2016 11:52:40 -0800 (PST)
Raw View
------=_Part_260_1882086389.1453665160209
Content-Type: multipart/alternative;
boundary="----=_Part_261_915135842.1453665160209"
------=_Part_261_915135842.1453665160209
Content-Type: text/plain; charset=UTF-8
On Saturday, January 23, 2016 at 9:13:48 PM UTC-5, Martin Molzer wrote:
>
> Just want to post a question I asked on stackoverflow where a comment was
> that my code wasn't future proof. It was about a class that could not be
> created on the heap, relying on a deleted copy and move constructor and the
> fact that you can capture such a variable in a temporary:
>
> http://stackoverflow.com/questions/34948403/
>
> This proposal would destroy that use case, if it'd go through and actually
> open up a problem for me if there was no way to suppress the behaviour for
> a specific class.
>
.... and?
Here's the thing: C++ has no way to do what you want. And the language
features you are (ab)using to achieve it are not intended to provide that
functionality. So there's no reason we shouldn't have mandatory elision
just because it stops you from doing this.
It would be far better to propose a language feature that would actually
allow you to declare a class which can be forbidden from being heap
allocated. Everyone would be better off that way.
Also, it would allow users to stack allocate them and return them, through
forced elision, to whomever needed them within their scope. Thus making
stack-only classes more inherently useful. There could also be syntax for
storing them as NSDMs of other stack-only classes, again making it more
useful than your narrow use case.
> I have no proposition on how to tell the compiler that a specific class
> would not allow copy/move elision but if it would, to be consistent, I'd
> make it forbidden to do so, even in the cases that are currently allowed by
> the standard. But there should be a way to forbid/restrict - see
> private/protected move and copy constructors.
>
Forbidding or restricting what can and cannot be elided adds complexity for
little gain. Again, simply providing syntax to say that this class cannot
be heap allocated would be better.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_261_915135842.1453665160209
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<br><br>On Saturday, January 23, 2016 at 9:13:48 PM UTC-5, Martin Molzer wr=
ote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex=
;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">Just want=
to post a question I asked on stackoverflow where a comment was that my co=
de wasn't future proof. It was about a class that could not be created =
on the heap, relying on a deleted copy and move constructor and the fact th=
at you can capture such a variable in a temporary:<br><br><a href=3D"http:/=
/stackoverflow.com/questions/34948403/" target=3D"_blank" rel=3D"nofollow" =
onmousedown=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F%2F=
stackoverflow.com%2Fquestions%2F34948403%2F\46sa\75D\46sntz\0751\46usg\75AF=
QjCNG270R5DmWF9Uz1mLYxIvi9wANX_Q';return true;" onclick=3D"this.href=3D=
'http://www.google.com/url?q\75http%3A%2F%2Fstackoverflow.com%2Fquestio=
ns%2F34948403%2F\46sa\75D\46sntz\0751\46usg\75AFQjCNG270R5DmWF9Uz1mLYxIvi9w=
ANX_Q';return true;">http://stackoverflow.com/<wbr>questions/34948403/<=
/a><br><br>This proposal would destroy that use case, if it'd go throug=
h and actually open up a problem for me if there was no way to suppress the=
behaviour for a specific class.<br></div></blockquote><div><br>... and?<br=
><br>Here's the thing: C++ has no way to do what you want. And the lang=
uage features you are (ab)using to achieve it are not intended to provide t=
hat functionality. So there's no reason we shouldn't have mandatory=
elision just because it stops you from doing this.<br><br>It would be far =
better to propose a language feature that would actually allow you to decla=
re a class which can be forbidden from being heap allocated. Everyone would=
be better off that way.<br><br>Also, it would allow users to stack allocat=
e them and return them, through forced elision, to whomever needed them wit=
hin their scope. Thus making stack-only classes more inherently useful. The=
re could also be syntax for storing them as NSDMs of other stack-only class=
es, again making it more useful than your narrow use case.<br>=C2=A0<br></d=
iv><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;=
border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">I have no =
proposition on how to tell the compiler that a specific class would not all=
ow copy/move elision but if it would, to be consistent, I'd make it for=
bidden to do so, even in the cases that are currently allowed by the standa=
rd. But there should be a way to forbid/restrict - see private/protected mo=
ve and copy constructors.<br></div></blockquote><div><br>Forbidding or rest=
ricting what can and cannot be elided adds complexity for little gain. Agai=
n, simply providing syntax to say that this class cannot be heap allocated =
would be better.<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_261_915135842.1453665160209--
------=_Part_260_1882086389.1453665160209--
.
Author: Vishal Oza <vickoza@gmail.com>
Date: Sun, 24 Jan 2016 12:10:24 -0800 (PST)
Raw View
------=_Part_3499_2047881199.1453666224201
Content-Type: multipart/alternative;
boundary="----=_Part_3500_1368890572.1453666224201"
------=_Part_3500_1368890572.1453666224201
Content-Type: text/plain; charset=UTF-8
On Sunday, January 24, 2016 at 1:52:40 PM UTC-6, Nicol Bolas wrote:
>
>
>
> On Saturday, January 23, 2016 at 9:13:48 PM UTC-5, Martin Molzer wrote:
>>
>> Just want to post a question I asked on stackoverflow where a comment was
>> that my code wasn't future proof. It was about a class that could not be
>> created on the heap, relying on a deleted copy and move constructor and the
>> fact that you can capture such a variable in a temporary:
>>
>> http://stackoverflow.com/questions/34948403/
>>
>> This proposal would destroy that use case, if it'd go through and
>> actually open up a problem for me if there was no way to suppress the
>> behaviour for a specific class.
>>
>
> ... and?
>
> Here's the thing: C++ has no way to do what you want. And the language
> features you are (ab)using to achieve it are not intended to provide that
> functionality. So there's no reason we shouldn't have mandatory elision
> just because it stops you from doing this.
>
> It would be far better to propose a language feature that would actually
> allow you to declare a class which can be forbidden from being heap
> allocated. Everyone would be better off that way.
>
> Also, it would allow users to stack allocate them and return them, through
> forced elision, to whomever needed them within their scope. Thus making
> stack-only classes more inherently useful. There could also be syntax for
> storing them as NSDMs of other stack-only classes, again making it more
> useful than your narrow use case.
>
>
>> I have no proposition on how to tell the compiler that a specific class
>> would not allow copy/move elision but if it would, to be consistent, I'd
>> make it forbidden to do so, even in the cases that are currently allowed by
>> the standard. But there should be a way to forbid/restrict - see
>> private/protected move and copy constructors.
>>
>
> Forbidding or restricting what can and cannot be elided adds complexity
> for little gain. Again, simply providing syntax to say that this class
> cannot be heap allocated would be better.
>
would your idea be something like this:
class foo stackonly
{
//
};
where the keyword stackonly tell the compiler to not ever use new or delete
to allocate the object?
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_3500_1368890572.1453666224201
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<br><br>On Sunday, January 24, 2016 at 1:52:40 PM UTC-6, Nicol Bolas wrote:=
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;"><br><br>On Saturday, January 2=
3, 2016 at 9:13:48 PM UTC-5, Martin Molzer wrote:<blockquote class=3D"gmail=
_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr">Just want to post a question I asked on stac=
koverflow where a comment was that my code wasn't future proof. It was =
about a class that could not be created on the heap, relying on a deleted c=
opy and move constructor and the fact that you can capture such a variable =
in a temporary:<br><br><a href=3D"http://stackoverflow.com/questions/349484=
03/" rel=3D"nofollow" target=3D"_blank" onmousedown=3D"this.href=3D'htt=
p://www.google.com/url?q\75http%3A%2F%2Fstackoverflow.com%2Fquestions%2F349=
48403%2F\46sa\75D\46sntz\0751\46usg\75AFQjCNG270R5DmWF9Uz1mLYxIvi9wANX_Q=
9;;return true;" onclick=3D"this.href=3D'http://www.google.com/url?q\75=
http%3A%2F%2Fstackoverflow.com%2Fquestions%2F34948403%2F\46sa\75D\46sntz\07=
51\46usg\75AFQjCNG270R5DmWF9Uz1mLYxIvi9wANX_Q';return true;">http://sta=
ckoverflow.com/<wbr>questions/34948403/</a><br><br>This proposal would dest=
roy that use case, if it'd go through and actually open up a problem fo=
r me if there was no way to suppress the behaviour for a specific class.<br=
></div></blockquote><div><br>... and?<br><br>Here's the thing: C++ has =
no way to do what you want. And the language features you are (ab)using to =
achieve it are not intended to provide that functionality. So there's n=
o reason we shouldn't have mandatory elision just because it stops you =
from doing this.<br><br>It would be far better to propose a language featur=
e that would actually allow you to declare a class which can be forbidden f=
rom being heap allocated. Everyone would be better off that way.<br><br>Als=
o, it would allow users to stack allocate them and return them, through for=
ced elision, to whomever needed them within their scope. Thus making stack-=
only classes more inherently useful. There could also be syntax for storing=
them as NSDMs of other stack-only classes, again making it more useful tha=
n your narrow use case.<br>=C2=A0<br></div><blockquote class=3D"gmail_quote=
" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-le=
ft:1ex"><div dir=3D"ltr">I have no proposition on how to tell the compiler =
that a specific class would not allow copy/move elision but if it would, to=
be consistent, I'd make it forbidden to do so, even in the cases that =
are currently allowed by the standard. But there should be a way to forbid/=
restrict - see private/protected move and copy constructors.<br></div></blo=
ckquote><div><br>Forbidding or restricting what can and cannot be elided ad=
ds complexity for little gain. Again, simply providing syntax to say that t=
his class cannot be heap allocated would be better.<br></div></blockquote><=
div>would your =C2=A0idea be something like this:</div><div><div class=3D"p=
rettyprint" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break=
-word; background-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><=
div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">class</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> foo stackonly<br></span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br></span><span style=3D"color: #800;" class=3D"styled-by-prettify">=
//</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">};</span></div=
></code></div>where the keyword stackonly tell the compiler to not ever use=
new or delete to allocate the object?<br>=C2=A0</div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_3500_1368890572.1453666224201--
------=_Part_3499_2047881199.1453666224201--
.
Author: Patrice Roy <patricer@gmail.com>
Date: Sun, 24 Jan 2016 20:10:59 -0500
Raw View
--047d7bdc0ce0e77c6b052a1e3d46
Content-Type: text/plain; charset=UTF-8
Wouldn't that choice of words imply introducing the very concept of a stack
in the standard? As far as I know, it's not there currently (it's a good
thing in some ways, and an annoyance in others).
Just asking...
2016-01-24 15:10 GMT-05:00 Vishal Oza <vickoza@gmail.com>:
>
>
> On Sunday, January 24, 2016 at 1:52:40 PM UTC-6, Nicol Bolas wrote:
>>
>>
>>
>> On Saturday, January 23, 2016 at 9:13:48 PM UTC-5, Martin Molzer wrote:
>>>
>>> Just want to post a question I asked on stackoverflow where a comment
>>> was that my code wasn't future proof. It was about a class that could not
>>> be created on the heap, relying on a deleted copy and move constructor and
>>> the fact that you can capture such a variable in a temporary:
>>>
>>> http://stackoverflow.com/questions/34948403/
>>>
>>> This proposal would destroy that use case, if it'd go through and
>>> actually open up a problem for me if there was no way to suppress the
>>> behaviour for a specific class.
>>>
>>
>> ... and?
>>
>> Here's the thing: C++ has no way to do what you want. And the language
>> features you are (ab)using to achieve it are not intended to provide that
>> functionality. So there's no reason we shouldn't have mandatory elision
>> just because it stops you from doing this.
>>
>> It would be far better to propose a language feature that would actually
>> allow you to declare a class which can be forbidden from being heap
>> allocated. Everyone would be better off that way.
>>
>> Also, it would allow users to stack allocate them and return them,
>> through forced elision, to whomever needed them within their scope. Thus
>> making stack-only classes more inherently useful. There could also be
>> syntax for storing them as NSDMs of other stack-only classes, again making
>> it more useful than your narrow use case.
>>
>>
>>> I have no proposition on how to tell the compiler that a specific class
>>> would not allow copy/move elision but if it would, to be consistent, I'd
>>> make it forbidden to do so, even in the cases that are currently allowed by
>>> the standard. But there should be a way to forbid/restrict - see
>>> private/protected move and copy constructors.
>>>
>>
>> Forbidding or restricting what can and cannot be elided adds complexity
>> for little gain. Again, simply providing syntax to say that this class
>> cannot be heap allocated would be better.
>>
> would your idea be something like this:
> class foo stackonly
> {
> //
> };
> where the keyword stackonly tell the compiler to not ever use new or
> delete to allocate the object?
>
>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> https://groups.google.com/a/isocpp.org/group/std-proposals/.
>
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
--047d7bdc0ce0e77c6b052a1e3d46
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>Wouldn't that choice of words imply introducing t=
he very concept of a stack in the standard? As far as I know, it's not =
there currently (it's a good thing in some ways, and an annoyance in ot=
hers).<br><br></div>Just asking...<br></div><div class=3D"gmail_extra"><br>=
<div class=3D"gmail_quote">2016-01-24 15:10 GMT-05:00 Vishal Oza <span dir=
=3D"ltr"><<a href=3D"mailto:vickoza@gmail.com" target=3D"_blank">vickoza=
@gmail.com</a>></span>:<br><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class=3D=
""><br><br>On Sunday, January 24, 2016 at 1:52:40 PM UTC-6, Nicol Bolas wro=
te:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bo=
rder-left:1px #ccc solid;padding-left:1ex"><br><br>On Saturday, January 23,=
2016 at 9:13:48 PM UTC-5, Martin Molzer wrote:<blockquote class=3D"gmail_q=
uote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddin=
g-left:1ex"><div dir=3D"ltr">Just want to post a question I asked on stacko=
verflow where a comment was that my code wasn't future proof. It was ab=
out a class that could not be created on the heap, relying on a deleted cop=
y and move constructor and the fact that you can capture such a variable in=
a temporary:<br><br><a href=3D"http://stackoverflow.com/questions/34948403=
/" rel=3D"nofollow" target=3D"_blank">http://stackoverflow.com/questions/34=
948403/</a><br><br>This proposal would destroy that use case, if it'd g=
o through and actually open up a problem for me if there was no way to supp=
ress the behaviour for a specific class.<br></div></blockquote><div><br>...=
and?<br><br>Here's the thing: C++ has no way to do what you want. And =
the language features you are (ab)using to achieve it are not intended to p=
rovide that functionality. So there's no reason we shouldn't have m=
andatory elision just because it stops you from doing this.<br><br>It would=
be far better to propose a language feature that would actually allow you =
to declare a class which can be forbidden from being heap allocated. Everyo=
ne would be better off that way.<br><br>Also, it would allow users to stack=
allocate them and return them, through forced elision, to whomever needed =
them within their scope. Thus making stack-only classes more inherently use=
ful. There could also be syntax for storing them as NSDMs of other stack-on=
ly classes, again making it more useful than your narrow use case.<br>=C2=
=A0<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-lef=
t:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">I hav=
e no proposition on how to tell the compiler that a specific class would no=
t allow copy/move elision but if it would, to be consistent, I'd make i=
t forbidden to do so, even in the cases that are currently allowed by the s=
tandard. But there should be a way to forbid/restrict - see private/protect=
ed move and copy constructors.<br></div></blockquote><div><br>Forbidding or=
restricting what can and cannot be elided adds complexity for little gain.=
Again, simply providing syntax to say that this class cannot be heap alloc=
ated would be better.<br></div></blockquote></span><div>would your =C2=A0id=
ea be something like this:</div><div><div style=3D"border:1px solid rgb(187=
,187,187);word-wrap:break-word;background-color:rgb(250,250,250)"><code><di=
v><span style=3D"color:#008">class</span><span style=3D"color:#000"> foo st=
ackonly<br></span><span style=3D"color:#660">{</span><span style=3D"color:#=
000"><br></span><span style=3D"color:#800">//</span><span style=3D"color:#0=
00"><br></span><span style=3D"color:#660">};</span></div></code></div>where=
the keyword stackonly tell the compiler to not ever use new or delete to a=
llocate the object?<br>=C2=A0</div><div class=3D"HOEnZb"><div class=3D"h5">
<p></p>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/" target=3D"_blank">https://groups.google.com/a/isocpp.org/g=
roup/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--047d7bdc0ce0e77c6b052a1e3d46--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sun, 24 Jan 2016 18:14:16 -0800 (PST)
Raw View
------=_Part_1858_334591225.1453688057076
Content-Type: multipart/alternative;
boundary="----=_Part_1859_1278543928.1453688057076"
------=_Part_1859_1278543928.1453688057076
Content-Type: text/plain; charset=UTF-8
On Sunday, January 24, 2016 at 8:11:01 PM UTC-5, Patrice Roy wrote:
>
> Wouldn't that choice of words imply introducing the very concept of a
> stack in the standard? As far as I know, it's not there currently (it's a
> good thing in some ways, and an annoyance in others).
>
We're not making a formal proposal; we know what we're talking about, so
using loose language is fine.
My point was simply that his backdoor method for making such types would be
better handled by an explicit feature, not by gimping a genuinely useful
feature like guaranteed elision.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_1859_1278543928.1453688057076
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Sunday, January 24, 2016 at 8:11:01 PM UTC-5, Patrice R=
oy wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: =
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div=
>Wouldn't that choice of words imply introducing the very concept of a =
stack in the standard? As far as I know, it's not there currently (it&#=
39;s a good thing in some ways, and an annoyance in others).<br></div></div=
></blockquote><div><br>We're not making a formal proposal; we know what=
we're talking about, so using loose language is fine.</div><br>My poin=
t was simply that his backdoor method for making such types would be better=
handled by an explicit feature, not by gimping a genuinely useful feature =
like guaranteed elision.<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_1859_1278543928.1453688057076--
------=_Part_1858_334591225.1453688057076--
.
Author: Patrice Roy <patricer@gmail.com>
Date: Sun, 24 Jan 2016 21:28:03 -0500
Raw View
--001a113ecbba858445052a1f510a
Content-Type: text/plain; charset=UTF-8
Cool; there's something there, though, which explains my enquiry.
For threads, there's an actual need for offering a way to specify the
required stack size at construction time (this cannot be achieved with most
operating systems once the thread has been created, which excludes using
native_handle), so we'll have to work something on that side for some
(important) specialized users.
It's not the subject of this discussion, so I did not want to pollute the
exchanges with this topic (peripheral for the moment), but should the
relation-to-stack issue remain relevant, we might have cross-concerns here.
Cheers!
2016-01-24 21:14 GMT-05:00 Nicol Bolas <jmckesson@gmail.com>:
> On Sunday, January 24, 2016 at 8:11:01 PM UTC-5, Patrice Roy wrote:
>>
>> Wouldn't that choice of words imply introducing the very concept of a
>> stack in the standard? As far as I know, it's not there currently (it's a
>> good thing in some ways, and an annoyance in others).
>>
>
> We're not making a formal proposal; we know what we're talking about, so
> using loose language is fine.
>
> My point was simply that his backdoor method for making such types would
> be better handled by an explicit feature, not by gimping a genuinely useful
> feature like guaranteed elision.
>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> https://groups.google.com/a/isocpp.org/group/std-proposals/.
>
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
--001a113ecbba858445052a1f510a
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>Cool; there's something there, though, which expl=
ains my enquiry.<br><br>For threads, there's an actual need for offerin=
g a way to specify the required stack size at construction time (this canno=
t be achieved with most operating systems once the thread has been created,=
which excludes using native_handle), so we'll have to work something o=
n that side for some (important) specialized users.<br><br>It's not the=
subject of this discussion, so I did not want to pollute the exchanges wit=
h this topic (peripheral for the moment), but should the relation-to-stack =
issue remain relevant, we might have cross-concerns here.<br><br></div>Chee=
rs!<br></div><div class=3D"gmail_extra"><br><div class=3D"gmail_quote">2016=
-01-24 21:14 GMT-05:00 Nicol Bolas <span dir=3D"ltr"><<a href=3D"mailto:=
jmckesson@gmail.com" target=3D"_blank">jmckesson@gmail.com</a>></span>:<=
br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left=
:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><span class=3D"">On Sund=
ay, January 24, 2016 at 8:11:01 PM UTC-5, Patrice Roy wrote:<blockquote cla=
ss=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc=
solid;padding-left:1ex"><div dir=3D"ltr"><div>Wouldn't that choice of =
words imply introducing the very concept of a stack in the standard? As far=
as I know, it's not there currently (it's a good thing in some way=
s, and an annoyance in others).<br></div></div></blockquote></span><div><br=
>We're not making a formal proposal; we know what we're talking abo=
ut, so using loose language is fine.</div><br>My point was simply that his =
backdoor method for making such types would be better handled by an explici=
t feature, not by gimping a genuinely useful feature like guaranteed elisio=
n.<br></div><div class=3D"HOEnZb"><div class=3D"h5">
<p></p>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/" target=3D"_blank">https://groups.google.com/a/isocpp.org/g=
roup/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--001a113ecbba858445052a1f510a--
.