Topic: Propose a smart convertor function
Author: Zijie He <hzj_jie@hotmail.com>
Date: Mon, 2 Mar 2015 17:28:17 -0800 (PST)
Raw View
------=_Part_4142_636352871.1425346097282
Content-Type: multipart/alternative;
boundary="----=_Part_4143_714140837.1425346097282"
------=_Part_4143_714140837.1425346097282
Content-Type: text/plain; charset=UTF-8
Hi, all,
I would like to propose a smart convertor function to do the conversion
between two known or unknown types, which can, in most cases, replace
existing cast keywords, with a consistent behavior and comparable
performance.
Briefly, it uses type_traits in c++11 to look for the best way to do the
conversion. And instead of compiling error, it throws runtime error.
If assignable, use operator=(const T1&, T2&) <copy_assign>.
If constructible, use T2::T2(const T1&) <copy_constructible>.
If T1 has member function bool convert_to(T2&), use bool
T1::convert_to(T2&) <copy_convert_to, optional>.
If nothing above matches, always return false <copy_failure>.
struct copy_assign
{
template <typename T1, typename T2>
static bool copy(const T1& i, T2& o)
{
o = i;
return true;
}
};
struct copy_constructible
{
template <typename T1, typename T2>
static bool copy(const T1& i, T2& o)
{
new (&o) T2(i);
return true;
}
};
struct copy_convert_to
{
template <typename T1, typename T2>
static bool copy(const T1& i, T2& o)
{
return i.convert_to(o);
}
};
struct copy_failure
{
template <typename T1, typename T2>
static bool copy(const T1& i, T2& o)
{
return false;
}
};
struct class_convertor
{
private:
HAS_CONST_MEMBER_FUNCTION(convert_to);
public:
template <typename T1, typename T2>
static bool copy(const T1& i, T2& o)
{
typedef typename std::conditional<
has_const_member_function_convert_to<T1,
bool, T2&>::value,
copy_convert_to,
copy_failure
>::type
copy_type;
return copy_type::copy(i, o);
}
};
template <typename T1, typename T2>
static bool convert(const T1& i, T2& o)
{
typedef typename std::conditional<
// std::is_convertible<T1, T2>::value ||
std::is_assignable<T2&, T1>::value,
copy_assign,
typename std::conditional<
std::is_constructible<T2, const
T1&>::value,
copy_constructible,
typename std::conditional<
std::is_class<T1>::value,
class_convertor,
copy_failure
>::type
>::type
>::type
copy_type;
return copy_type::copy(i, o);
}
With a set of speed-up functions,
const static char* True = "true";
const static char* False = "false";
static bool convert(const std::string& i, std::string& o)
{
o = i;
return true;
}
static bool convert(const char* i, std::string& o)
{
o = i;
return true;
}
static bool convert(const std::string& i, bool& o)
{
std::string s(i);
boost::algorithm::to_lower(s);
o = (s == True);
return true;
}
static bool convert(const char* i, bool& o)
{
return convert(std::string(i), o);
}
static bool convert(const bool& i, std::string& o)
{
o = std::string(i ? True : False);
return true;
}
template <typename T>
static bool convert(const std::string& i, T& o)
{
return from_str(i, o);
}
template <typename T>
static bool convert(const T& i, std::string& o)
{
return to_str(i, o);
}
template <typename T>
static bool convert(const char* i, T& o)
{
return convert(std::string(i), o);
}
And a static class to provide a consistent interface.
const static class convertor_t
{
public:
template <typename T1, typename T2>
bool operator()(const T1& i, T2& o) const
{
return converts::convert(i, o);
}
template <typename T1, typename T2>
T2 convert(const T1& i) const
{
T2 o { };
assert(operator()(i, o));
return o;
}
private:
convertor_t() = default;
CONST_SINGLETON(convertor_t);
}& convertor = convertor_t::instance();
Please refer to
https://github.com/Hzj-jie/osi/blob/master/utt_cases/utils/convertor_test.hpp for
the usage.
A set of r-value reference overloads can be added to improve the
performance. Say bool convertor_t::operator()(T1&& i, T2& o) const.
--
---
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_4143_714140837.1425346097282
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Hi, all,<div>I would like to propose a smart convertor fun=
ction to do the conversion between two known or unknown types, which can, i=
n most cases, replace existing cast keywords, with a consistent behavior an=
d comparable performance.</div><div>Briefly, it uses type_traits in c++11 t=
o look for the best way to do the conversion. And instead of compiling erro=
r, it throws runtime error.</div><div>If assignable, use operator=3D(const =
T1&, T2&) <copy_assign>.</div><div>If constructible, use T2::=
T2(const T1&) <copy_constructible>.</div><div>If T1 has member fu=
nction bool convert_to(T2&), use bool T1::convert_to(T2&) <copy_=
convert_to, optional>.</div><div>If nothing above matches, always return=
false <copy_failure>.</div><div><br></div><div><div class=3D"prettyp=
rint" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-word;=
background-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><div cl=
ass=3D"subprettyprint"><font color=3D"#660066"><div class=3D"subprettyprint=
"><br></div><div class=3D"subprettyprint"> struct copy_assign<=
/div><div class=3D"subprettyprint"> {</div><div class=3D"subpr=
ettyprint"> template <typename T1, typename T=
2></div><div class=3D"subprettyprint"> static=
bool copy(const T1& i, T2& o)</div><div class=3D"subprettyprint">&=
nbsp; {</div><div class=3D"subprettyprint"> &nbs=
p; o =3D i;</div><div class=3D"subprettyprint">=
return true;</div><div class=3D"s=
ubprettyprint"> }</div><div class=3D"subprettypr=
int"> };</div><div class=3D"subprettyprint"><br></div><div cla=
ss=3D"subprettyprint"> struct copy_constructible</div><div cla=
ss=3D"subprettyprint"> {</div><div class=3D"subprettyprint">&n=
bsp; template <typename T1, typename T2></div><d=
iv class=3D"subprettyprint"> static bool copy(co=
nst T1& i, T2& o)</div><div class=3D"subprettyprint"> =
{</div><div class=3D"subprettyprint"> &nb=
sp; new (&o) T2(i);</div><div class=3D"subprettyprint">&n=
bsp; return true;</div><div class=3D"sub=
prettyprint"> }</div><div class=3D"subprettyprin=
t"> };</div><div class=3D"subprettyprint"><br></div><div class=
=3D"subprettyprint"> struct copy_convert_to</div><div class=3D=
"subprettyprint"> {</div><div class=3D"subprettyprint"> =
template <typename T1, typename T2></div><div cl=
ass=3D"subprettyprint"> static bool copy(const T=
1& i, T2& o)</div><div class=3D"subprettyprint">  =
; {</div><div class=3D"subprettyprint"> &=
nbsp; return i.convert_to(o);</div><div class=3D"subprettyprint">&nb=
sp; }</div><div class=3D"subprettyprint"> =
};</div><div class=3D"subprettyprint"><br></div><div class=3D"subprettypri=
nt"> struct copy_failure</div><div class=3D"subprettyprint">&n=
bsp; {</div><div class=3D"subprettyprint">  =
; template <typename T1, typename T2></div><div class=3D"subprettypri=
nt"> static bool copy(const T1& i, T2& o=
)</div><div class=3D"subprettyprint"> {</div><di=
v class=3D"subprettyprint"> return=
false;</div><div class=3D"subprettyprint"> }</d=
iv><div class=3D"subprettyprint"> };</div><div class=3D"subpre=
ttyprint"><br></div><div class=3D"subprettyprint"> struct clas=
s_convertor</div><div class=3D"subprettyprint"> {</div><div cl=
ass=3D"subprettyprint"> private:</div><div class=3D"subprettyp=
rint"> HAS_CONST_MEMBER_FUNCTION(convert_to);</d=
iv><div class=3D"subprettyprint"><br></div><div class=3D"subprettyprint">&n=
bsp; public:</div><div class=3D"subprettyprint"> =
template <typename T1, typename T2></div><div class=3D"subpre=
ttyprint"> static bool copy(const T1& i, T2&=
amp; o)</div><div class=3D"subprettyprint"> {</d=
iv><div class=3D"subprettyprint"> =
typedef typename std::conditional<</div><div class=3D"subprettyprint">&n=
bsp; =
has_const_member_function_convert_=
to<T1, bool, T2&>::value,</div><div class=3D"subprettyprint">&nbs=
p; &n=
bsp; copy_convert_to,</div><div class=3D"=
subprettyprint"> &nb=
sp; copy_failure</di=
v><div class=3D"subprettyprint"> &=
nbsp; >::type</di=
v><div class=3D"subprettyprint"> &=
nbsp; copy_type;</di=
v><div class=3D"subprettyprint"> r=
eturn copy_type::copy(i, o);</div><div class=3D"subprettyprint"> &nbs=
p; }</div><div class=3D"subprettyprint"> };</div=
><div class=3D"subprettyprint"><br></div><div class=3D"subprettyprint">&nbs=
p; template <typename T1, typename T2></div><div class=3D"subp=
rettyprint"> static bool convert(const T1& i, T2& o)</=
div><div class=3D"subprettyprint"> {</div><div class=3D"subpre=
ttyprint"> typedef typename std::conditional<=
</div><div class=3D"subprettyprint"> &nbs=
p; // std::is=
_convertible<T1, T2>::value ||</div><div class=3D"subprettyprint">&nb=
sp; &=
nbsp; std::is_assignable<T2&, T1>::value,</di=
v><div class=3D"subprettyprint"> &=
nbsp; copy_assign,</=
div><div class=3D"subprettyprint"> =
typename std=
::conditional<</div><div class=3D"subprettyprint"> &=
nbsp; =
std::is_constructible<T2, const T1&>::value,=
</div><div class=3D"subprettyprint"> &nbs=
p; &n=
bsp;copy_constructible,</div><div class=3D"subprettyprint"> &n=
bsp; =
typename std::conditional<</div><div class=3D=
"subprettyprint"> &n=
bsp; s=
td::is_class<T1>::value,</div><div class=3D"subprettyprint"> &n=
bsp; =
class_convertor,</div><div =
class=3D"subprettyprint"> &=
nbsp; =
copy_failure</div><div class=3D"subprettyprint"> =
&nbs=
p; >::type</div><div class=3D"subprettyprint"> =
&nbs=
p; >::type</div><div class=3D"subprettyprint"> =
&nbs=
p; >::type</div><div class=3D"subprettyprint"> =
copy_=
type;</div><div class=3D"subprettyprint"> return=
copy_type::copy(i, o);</div><div class=3D"subprettyprint"> }<=
/div></font></div></code></div><br>With a set of speed-up functions,</div><=
div><div class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187, 187=
); word-wrap: break-word; background-color: rgb(250, 250, 250);"><code clas=
s=3D"prettyprint"><div class=3D"subprettyprint"><div class=3D"subprettyprin=
t"><font color=3D"#660066"> const static char* True =3D "true"=
;</font></div><div class=3D"subprettyprint"><font color=3D"#660066"> =
const static char* False =3D "false";</font></div><div class=3D"subp=
rettyprint"><font color=3D"#660066"><br></font></div><div class=3D"subprett=
yprint"><font color=3D"#660066"> static bool convert(const std=
::string& i, std::string& o)</font></div><div class=3D"subprettypri=
nt"><font color=3D"#660066"> {</font></div><div class=3D"subpr=
ettyprint"><font color=3D"#660066"> o =3D i;</fo=
nt></div><div class=3D"subprettyprint"><font color=3D"#660066">  =
; return true;</font></div><div class=3D"subprettyprint"><fon=
t color=3D"#660066"> }</font></div><div class=3D"subprettyprin=
t"><font color=3D"#660066"><br></font></div><div class=3D"subprettyprint"><=
font color=3D"#660066"> static bool convert(const char* i, std=
::string& o)</font></div><div class=3D"subprettyprint"><font color=3D"#=
660066"> {</font></div><div class=3D"subprettyprint"><font col=
or=3D"#660066"> o =3D i;</font></div><div class=
=3D"subprettyprint"><font color=3D"#660066"> ret=
urn true;</font></div><div class=3D"subprettyprint"><font color=3D"#660066"=
> }</font></div><div class=3D"subprettyprint"><font color=3D"#=
660066"><br></font></div><div class=3D"subprettyprint"><font color=3D"#6600=
66"> static bool convert(const std::string& i, bool& o=
)</font></div><div class=3D"subprettyprint"><font color=3D"#660066"> =
{</font></div><div class=3D"subprettyprint"><font color=3D"#660066">=
std::string s(i);</font></div><div class=3D"sub=
prettyprint"><font color=3D"#660066"> boost::alg=
orithm::to_lower(s);</font></div><div class=3D"subprettyprint"><font color=
=3D"#660066"> o =3D (s =3D=3D True);</font></div=
><div class=3D"subprettyprint"><font color=3D"#660066"> =
return true;</font></div><div class=3D"subprettyprint"><font color=
=3D"#660066"> }</font></div><div class=3D"subprettyprint"><fon=
t color=3D"#660066"><br></font></div><div class=3D"subprettyprint"><font co=
lor=3D"#660066"> static bool convert(const char* i, bool& =
o)</font></div><div class=3D"subprettyprint"><font color=3D"#660066"> =
{</font></div><div class=3D"subprettyprint"><font color=3D"#660066"=
> return convert(std::string(i), o);</font></div=
><div class=3D"subprettyprint"><font color=3D"#660066"> }</fon=
t></div><div class=3D"subprettyprint"><font color=3D"#660066"><br></font></=
div><div class=3D"subprettyprint"><font color=3D"#660066"> sta=
tic bool convert(const bool& i, std::string& o)</font></div><div cl=
ass=3D"subprettyprint"><font color=3D"#660066"> {</font></div>=
<div class=3D"subprettyprint"><font color=3D"#660066"> =
o =3D std::string(i ? True : False);</font></div><div class=3D"subpr=
ettyprint"><font color=3D"#660066"> return true;=
</font></div><div class=3D"subprettyprint"><font color=3D"#660066"> &=
nbsp; }</font></div><div class=3D"subprettyprint"><font color=3D"#660066"><=
br></font></div><div class=3D"subprettyprint"><font color=3D"#660066"> =
; template <typename T></font></div><div class=3D"subprettypri=
nt"><font color=3D"#660066"> static bool convert(const std::st=
ring& i, T& o)</font></div><div class=3D"subprettyprint"><font colo=
r=3D"#660066"> {</font></div><div class=3D"subprettyprint"><fo=
nt color=3D"#660066"> return from_str(i, o);</fo=
nt></div><div class=3D"subprettyprint"><font color=3D"#660066">  =
; }</font></div><div class=3D"subprettyprint"><font color=3D"#660066"><br><=
/font></div><div class=3D"subprettyprint"><font color=3D"#660066"> &n=
bsp; template <typename T></font></div><div class=3D"subprettyprint">=
<font color=3D"#660066"> static bool convert(const T& i, s=
td::string& o)</font></div><div class=3D"subprettyprint"><font color=3D=
"#660066"> {</font></div><div class=3D"subprettyprint"><font c=
olor=3D"#660066"> return to_str(i, o);</font></d=
iv><div class=3D"subprettyprint"><font color=3D"#660066"> }</f=
ont></div><div class=3D"subprettyprint"><font color=3D"#660066"><br></font>=
</div><div class=3D"subprettyprint"><font color=3D"#660066"> t=
emplate <typename T></font></div><div class=3D"subprettyprint"><font =
color=3D"#660066"> static bool convert(const char* i, T& o=
)</font></div><div class=3D"subprettyprint"><font color=3D"#660066"> =
{</font></div><div class=3D"subprettyprint"><font color=3D"#660066">=
return convert(std::string(i), o);</font></div>=
<div class=3D"subprettyprint"><font color=3D"#660066"> }</font=
></div></div></code></div><br>And a static class to provide a consistent in=
terface.</div><div><div class=3D"prettyprint" style=3D"border: 1px solid rg=
b(187, 187, 187); word-wrap: break-word; background-color: rgb(250, 250, 25=
0);"><code class=3D"prettyprint"><div class=3D"subprettyprint"><font color=
=3D"#660066"><div class=3D"subprettyprint"><br></div><div class=3D"subprett=
yprint">const static class convertor_t</div><div class=3D"subprettyprint">{=
</div><div class=3D"subprettyprint">public:</div><div class=3D"subprettypri=
nt"> template <typename T1, typename T2></div><div class=
=3D"subprettyprint"> bool operator()(const T1& i, T2& =
o) const</div><div class=3D"subprettyprint"> {</div><div class=
=3D"subprettyprint"> return converts::convert(i,=
o);</div><div class=3D"subprettyprint"> }</div><div class=3D"=
subprettyprint"><br></div><div class=3D"subprettyprint"> templ=
ate <typename T1, typename T2></div><div class=3D"subprettyprint">&nb=
sp; T2 convert(const T1& i) const</div><div class=3D"subprettypr=
int"> {</div><div class=3D"subprettyprint">  =
; T2 o { };</div><div class=3D"subprettyprint"> =
assert(operator()(i, o));</div><div class=3D"subprettyprint"> =
return o;</div><div class=3D"subprettyprint"> &n=
bsp; }</div><div class=3D"subprettyprint"><br></div><div class=3D"subpretty=
print">private:</div><div class=3D"subprettyprint"> convertor_=
t() =3D default;</div><div class=3D"subprettyprint"><br></div><div class=3D=
"subprettyprint"> CONST_SINGLETON(convertor_t);</div><div clas=
s=3D"subprettyprint">}& convertor =3D convertor_t::instance();</div></f=
ont></div></code></div><br>Please refer to <a href=3D"https://github.com/Hz=
j-jie/osi/blob/master/utt_cases/utils/convertor_test.hpp">https://github.co=
m/Hzj-jie/osi/blob/master/utt_cases/utils/convertor_test.hpp</a> for t=
he usage.</div><div><br></div><div>A set of r-value reference overloads can=
be added to improve the performance. Say bool convertor_t::operator()(T1&a=
mp;& i, T2& o) const.</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_4143_714140837.1425346097282--
------=_Part_4142_636352871.1425346097282--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 2 Mar 2015 17:57:14 -0800 (PST)
Raw View
------=_Part_1986_832607512.1425347834561
Content-Type: multipart/alternative;
boundary="----=_Part_1987_1116401038.1425347834567"
------=_Part_1987_1116401038.1425347834567
Content-Type: text/plain; charset=UTF-8
The problem you seem to be trying to solve seems to be getting runtime
error return values for conversion failures, rather than compile-time ones.
Because right now, the expression:
T1 t1 = t2;
Will search through several ways of handling this conversion. It'll check
to see if T1 has an implicit constructor that takes a T2. If not, then
it'll check T2 for an implicit conversion operator to type T1 (as well as
some other type that will fit one of T1's constructors, if I recall
correctly).
There's no point in checking the copy assignment operator, since anyone who
has a copy assignment and no copy constructor doesn't deserve to have
compiling code. And I see no point in using this on objects which are
already constructed. If you wanted to do that, just use your copy
assignment operator:
t1 = t2;
With the appropriate implicit constructors/conversions, this will work just
fine.
So it seems clear to me that C++ can handle the "convert to X" part just
fine. So the only problem your solution solves is turning the failure to
find a conversion function into a runtime error rather than a compile-time
one. And... I'm not sure that this should be considered a problem. After
all, if none of those functions are defined at compile time, they
*certainly* won't be defined by runtime.
The only thing left is what happens if conversion fails. But if conversion
fails, that's the equivalent of a constructor failure. And we have a
*solution* for signaling constructor failures: throw an exception.
So it's not clear to me what the point of this is. It would only seem
worthwhile if:
1) You don't like constructors.
2) You don't like conversion operators.
3) You don't like exceptions.
The C++ language covers your problem domain just fine. C++ allows either T1
or T2 to execute the conversion. C++ will complain if you ask it to do a
conversion you haven't properly told it how to convert. And C++ has a clear
mechanism for signaling errors on conversion failure.
So what deficiency are you addressing here?
--
---
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_1987_1116401038.1425347834567
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">The problem you seem to be trying to solve seems to be get=
ting runtime error return values for conversion failures, rather than compi=
le-time ones. Because right now, the expression:<br><br>T1 t1 =3D t2;<br><b=
r>Will search through several ways of handling this conversion. It'll check=
to see if T1 has an implicit constructor that takes a T2. If not, then it'=
ll check T2 for an implicit conversion operator to type T1 (as well as some=
other type that will fit one of T1's constructors, if I recall correctly).=
<br><br>There's no point in checking the copy assignment operator, since an=
yone who has a copy assignment and no copy constructor doesn't deserve to h=
ave compiling code. And I see no point in using this on objects which are a=
lready constructed. If you wanted to do that, just use your copy assignment=
operator:<br><br>t1 =3D t2;<br><br>With the appropriate implicit construct=
ors/conversions, this will work just fine.<br><br>So it seems clear to me t=
hat C++ can handle the "convert to X" part just fine. So the only problem y=
our solution solves is turning the failure to find a conversion function in=
to a runtime error rather than a compile-time one. And... I'm not sure that=
this should be considered a problem. After all, if none of those functions=
are defined at compile time, they <i>certainly</i> won't be defined by run=
time.<br><br>The only thing left is what happens if conversion fails. But i=
f conversion fails, that's the equivalent of a constructor failure. And we =
have a <i>solution</i> for signaling constructor failures: throw an excepti=
on.<br><br>So it's not clear to me what the point of this is. It would only=
seem worthwhile if:<br><br>1) You don't like constructors.<br><br>2) You d=
on't like conversion operators.<br><br>3) You don't like exceptions.<br><br=
>The C++ language covers your problem domain just fine. C++ allows either T=
1 or T2 to execute the conversion. C++ will complain if you ask it to do a =
conversion you haven't properly told it how to convert. And C++ has a clear=
mechanism for signaling errors on conversion failure.<br><br>So what defic=
iency are you addressing here?<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_1987_1116401038.1425347834567--
------=_Part_1986_832607512.1425347834561--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 2 Mar 2015 18:13:22 -0800 (PST)
Raw View
------=_Part_4341_719381775.1425348802294
Content-Type: multipart/alternative;
boundary="----=_Part_4342_316559815.1425348802294"
------=_Part_4342_316559815.1425348802294
Content-Type: text/plain; charset=UTF-8
Wait, I think I've figured out the problem you're trying to solve. It's the
performance difference between:
T1 t1 = t2;
and
t1 = t2;
The first case will be optimal either because it's calling T1's constructor
on a reference to t2, or because it elides the return value from T2's
conversion operator. Either way, you're constructing the object in place,
even if it doesn't seem like it.
Whereas, when t1 is a live object, the only way for this to be optimal is
if T1 has an assignment operator overload for T2. If T1 doesn't have one,
then it becomes an execution of T2's conversion operator, followed by copy
assignment int T1.
My thoughts on this are as follows: does this *really* matter? Does this
really matter enough to propose a standard library feature (even ignoring
the lack of equivalence to the C++ language feature) for the specific case
of conversion into a live object?
Is there some reason why you can't just give T1 an optimal assignment
operator overload? I mean, you're going to have to write the code
*somewhere*. It may as well be in T1.
In the rare case where T1 doesn't and isn't allowed to know enough to
construct itself from T2's public interface... just write a special case
for that particular condition. How often are you going around
conversion-assigning into live objects, anyway?
I doubt it's enough to be worth a library feature. Let alone one that's as
non-standard as what you proposed.
--
---
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_4342_316559815.1425348802294
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Wait, I think I've figured out the problem you're trying t=
o solve. It's the performance difference between:<br><br>T1 t1 =3D t2;<br><=
br>and<br><br>t1 =3D t2;<br><br>The first case will be optimal either becau=
se it's calling T1's constructor on a reference to t2, or because it elides=
the return value from T2's conversion operator. Either way, you're constru=
cting the object in place, even if it doesn't seem like it.<br><br>Whereas,=
when t1 is a live object, the only way for this to be optimal is if T1 has=
an assignment operator overload for T2. If T1 doesn't have one, then it be=
comes an execution of T2's conversion operator, followed by copy assignment=
int T1.<br><br>My thoughts on this are as follows: does this <i>really</i>=
matter? Does this really matter enough to propose a standard library featu=
re (even ignoring the lack of equivalence to the C++ language feature) for =
the specific case of conversion into a live object?<br><br>Is there some re=
ason why you can't just give T1 an optimal assignment operator overload? I =
mean, you're going to have to write the code <i>somewhere</i>. It may as we=
ll be in T1.<br><br>In the rare case where T1 doesn't and isn't allowed to =
know enough to construct itself from T2's public interface... just write a =
special case for that particular condition. How often are you going around =
conversion-assigning into live objects, anyway?<br><br>I doubt it's enough =
to be worth a library feature. Let alone one that's as non-standard as what=
you proposed.<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_4342_316559815.1425348802294--
------=_Part_4341_719381775.1425348802294--
.
Author: Zijie He <hzj_jie@hotmail.com>
Date: Mon, 2 Mar 2015 18:28:24 -0800 (PST)
Raw View
------=_Part_956_135250147.1425349704956
Content-Type: multipart/alternative;
boundary="----=_Part_957_1111522103.1425349704956"
------=_Part_957_1111522103.1425349704956
Content-Type: text/plain; charset=UTF-8
The proposal is targeting three different problems,
1. is_assignable is much more than T1 t1 = t2;, check the following case,
#include <iostream>
#include <type_traits>
using namespace std;
class C
{
public:
C() = default;
C(int) { cout << "C(int)" << endl; }
};
class C2
{
public:
void operator=(int) { cout << "opertor=(int)" << endl; }
};
int main()
{
C c = 1;
// C2 c2 = 1;
C2 c2;
c2 = 1;
cout << is_assignable<C2&, int>::value << endl;
}
2. As you have mentioned, performance concern. There may be several ways to
convert from T1 to T2, while this implementation can help to select the
best one.
3. Typically in template programming, usually you do not know the types of
T1 and T2, while there may be several ways to convert from T1 to T2.
Several types may implements constructor, several types may implements
operator=. The behavior will be same, but in the template, you may need to
handle several cases. So this implementation is to separate the irrelevant
logic from this kind of templates.
On Tuesday, March 3, 2015 at 10:13:22 AM UTC+8, Nicol Bolas wrote:
>
> Wait, I think I've figured out the problem you're trying to solve. It's
> the performance difference between:
>
> T1 t1 = t2;
>
> and
>
> t1 = t2;
>
> The first case will be optimal either because it's calling T1's
> constructor on a reference to t2, or because it elides the return value
> from T2's conversion operator. Either way, you're constructing the object
> in place, even if it doesn't seem like it.
>
> Whereas, when t1 is a live object, the only way for this to be optimal is
> if T1 has an assignment operator overload for T2. If T1 doesn't have one,
> then it becomes an execution of T2's conversion operator, followed by copy
> assignment int T1.
>
> My thoughts on this are as follows: does this *really* matter? Does this
> really matter enough to propose a standard library feature (even ignoring
> the lack of equivalence to the C++ language feature) for the specific case
> of conversion into a live object?
>
> Is there some reason why you can't just give T1 an optimal assignment
> operator overload? I mean, you're going to have to write the code
> *somewhere*. It may as well be in T1.
>
> In the rare case where T1 doesn't and isn't allowed to know enough to
> construct itself from T2's public interface... just write a special case
> for that particular condition. How often are you going around
> conversion-assigning into live objects, anyway?
>
> I doubt it's enough to be worth a library feature. Let alone one that's as
> non-standard as what you proposed.
>
--
---
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_957_1111522103.1425349704956
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">The proposal is targeting three different problems,<div>1.=
is_assignable is much more than T1 t1 =3D t2;, check the following case,</=
div><div><div class=3D"prettyprint" 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"><div class=3D"subprett=
yprint"><font color=3D"#660066"><br></font></div><div class=3D"subprettypri=
nt"><font color=3D"#660066">#include <iostream></font></div><div clas=
s=3D"subprettyprint"><font color=3D"#660066">#include <type_traits></=
font></div><div class=3D"subprettyprint"><font color=3D"#660066">using name=
space std;</font></div><div class=3D"subprettyprint"><font color=3D"#660066=
"><br></font></div><div class=3D"subprettyprint"><font color=3D"#660066">cl=
ass C</font></div><div class=3D"subprettyprint"><font color=3D"#660066">{</=
font></div><div class=3D"subprettyprint"><font color=3D"#660066">public:</f=
ont></div><div class=3D"subprettyprint"><font color=3D"#660066"> &nbs=
p; C() =3D default;</font></div><div class=3D"subprettyprint"><font color=
=3D"#660066"> C(int) { cout << "C(int)" << endl; }=
</font></div><div class=3D"subprettyprint"><font color=3D"#660066">};</font=
></div><div class=3D"subprettyprint"><font color=3D"#660066"><br></font></d=
iv><div class=3D"subprettyprint"><font color=3D"#660066">class C2</font></d=
iv><div class=3D"subprettyprint"><font color=3D"#660066">{</font></div><div=
class=3D"subprettyprint"><font color=3D"#660066">public:</font></div><div =
class=3D"subprettyprint"><font color=3D"#660066"> void operato=
r=3D(int) { cout << "opertor=3D(int)" << endl; }</font></div><d=
iv class=3D"subprettyprint"><font color=3D"#660066">};</font></div><div cla=
ss=3D"subprettyprint"><font color=3D"#660066"><br></font></div><div class=
=3D"subprettyprint"><font color=3D"#660066">int main()</font></div><div cla=
ss=3D"subprettyprint"><font color=3D"#660066">{</font></div><div class=3D"s=
ubprettyprint"><font color=3D"#660066"> C c =3D 1;</font></div=
><div class=3D"subprettyprint"><font color=3D"#660066"> // C2 =
c2 =3D 1;</font></div><div class=3D"subprettyprint"><font color=3D"#660066"=
> C2 c2;</font></div><div class=3D"subprettyprint"><font color=
=3D"#660066"> c2 =3D 1;</font></div><div class=3D"subprettypri=
nt"><font color=3D"#660066"> cout << is_assignable<C2=
&, int>::value << endl;</font></div><div class=3D"subprettypri=
nt"><font color=3D"#660066">}</font></div></div></code></div><div><br></div=
>2. As you have mentioned, performance concern. There may be several ways t=
o convert from T1 to T2, while this implementation can help to select the b=
est one.<br>3. Typically in template programming, usually you do not know t=
he types of T1 and T2, while there may be several ways to convert from T1 t=
o T2. Several types may implements constructor, several types may implement=
s operator=3D. The behavior will be same, but in the template, you may need=
to handle several cases. So this implementation is to separate the irrelev=
ant logic from this kind of templates.<br><br>On Tuesday, March 3, 2015 at =
10:13:22 AM UTC+8, Nicol Bolas wrote:<blockquote class=3D"gmail_quote" styl=
e=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left:=
1ex;"><div dir=3D"ltr">Wait, I think I've figured out the problem you're t=
rying to solve. It's the performance difference between:<br><br>T1 t1 =3D t=
2;<br><br>and<br><br>t1 =3D t2;<br><br>The first case will be optimal eithe=
r because it's calling T1's constructor on a reference to t2, or because it=
elides the return value from T2's conversion operator. Either way, you're =
constructing the object in place, even if it doesn't seem like it.<br><br>W=
hereas, when t1 is a live object, the only way for this to be optimal is if=
T1 has an assignment operator overload for T2. If T1 doesn't have one, the=
n it becomes an execution of T2's conversion operator, followed by copy ass=
ignment int T1.<br><br>My thoughts on this are as follows: does this <i>rea=
lly</i> matter? Does this really matter enough to propose a standard librar=
y feature (even ignoring the lack of equivalence to the C++ language featur=
e) for the specific case of conversion into a live object?<br><br>Is there =
some reason why you can't just give T1 an optimal assignment operator overl=
oad? I mean, you're going to have to write the code <i>somewhere</i>. It ma=
y as well be in T1.<br><br>In the rare case where T1 doesn't and isn't allo=
wed to know enough to construct itself from T2's public interface... just w=
rite a special case for that particular condition. How often are you going =
around conversion-assigning into live objects, anyway?<br><br>I doubt it's =
enough to be worth a library feature. Let alone one that's as non-standard =
as what you proposed.<br></div></blockquote></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_957_1111522103.1425349704956--
------=_Part_956_135250147.1425349704956--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 2 Mar 2015 22:13:06 -0800 (PST)
Raw View
------=_Part_4406_69524778.1425363186987
Content-Type: multipart/alternative;
boundary="----=_Part_4407_271839878.1425363186987"
------=_Part_4407_271839878.1425363186987
Content-Type: text/plain; charset=UTF-8
On Monday, March 2, 2015 at 9:28:25 PM UTC-5, Zijie He wrote:
>
> The proposal is targeting three different problems,
> 1. is_assignable is much more than T1 t1 = t2;
>
Actually, that's line is not an example of is_assignable at all. That
statement will never use the assignment operator; it will instead use an
appropriate conversion (either via an implicit constructor or via a single
implicit conversion operator call).
> 2. As you have mentioned, performance concern. There may be several ways
> to convert from T1 to T2, while this implementation can help to select the
> best one.
>
As previously stated, the only performance concern as things currently
stand is the rare case of performing a conversion into a live object. And
you have yet to explain why this case is important enough to bother with
such a change.
> 3. Typically in template programming, usually you do not know the types of
> T1 and T2, while there may be several ways to convert from T1 to T2.
>
There are not "several" ways to convert; there are precisely two: either
via initialization of a new value or via copy/move-into-a-live-object. Both
ways in C++ use the assignment operator (though the initialization case
doesn't call the overload for it). The language supports these cases well
enough without template metaprogramming or 'convert_to' or other such stuff.
So what are these "several ways" you keep talking about optimizing for?
What are the other alternatives?
Several types may implements constructor, several types may implements
> operator=. The behavior will be same, but in the template, you may need to
> handle several cases. So this implementation is to separate the irrelevant
> logic from this kind of templates.
>
Nonsense. In a template, you impose some particular requirement on the
type. Sans-concepts, this requirement is implicit. If you template needs to
"convert" from one type to another, we have an acceptable syntax to do that:
T1 t1 = t2;
There are no performance issues with this. There is no "irrelevant logic"
needed to make this work. You don't need any special cases. You simply use
the language features.
The user will implement the implicit conversion in T1 or T2 at their
leisure, and your template code will adapt to their choice. There are no
cases for you to consider. So long as the user has done their jobs in
making T1 and T2, this will work.
And if they didn't, then they get a compiler error. As they should.
If you want to be nicer to the user (so the conversions don't have to be
implicit), you invoke direct initialization:
T1 t1(t2);
--
---
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_4407_271839878.1425363186987
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Monday, March 2, 2015 at 9:28:25 PM UTC-5, Ziji=
e He 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">Th=
e proposal is targeting three different problems,<div>1. is_assignable is m=
uch more than T1 t1 =3D t2;</div></div></blockquote><div><br>Actually, that=
's line is not an example of is_assignable at all. That statement will neve=
r use
the assignment operator; it will instead use an appropriate conversion (ei=
ther via an implicit constructor or via a single implicit conversion operat=
or call).<br> </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">2. As you have mentioned, performance concern. There may be sev=
eral ways to convert from T1 to T2, while this implementation can help to s=
elect the best one.<br></div></blockquote><div><br>As previously stated, th=
e only performance concern as things currently stand is the rare case of pe=
rforming a conversion into a live object. And you have yet to explain why t=
his case is important enough to bother with such a change.<br> </div><=
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"><div>3. Typica=
lly in template programming, usually you do not know the types of T1 and T2=
, while there may be several ways to convert from T1 to T2.</div></div></bl=
ockquote><div><br>There are not "several" ways to convert; there are precis=
ely two: either via initialization of a new value or via copy/move-into-a-l=
ive-object. Both ways in C++ use the assignment operator (though the initia=
lization case doesn't call the overload for it). The language supports thes=
e cases well enough without template metaprogramming or 'convert_to' or oth=
er such stuff.<br><br>So what are these "several ways" you keep talking abo=
ut optimizing for? What are the other alternatives?<br><br></div><blockquot=
e 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>Several types may =
implements constructor, several types may implements operator=3D. The behav=
ior will be same, but in the template, you may need to handle several cases=
.. So this implementation is to separate the irrelevant logic from this kind=
of templates.<br></div></div></blockquote><div><br>Nonsense. In a template=
, you impose some particular requirement on the type. Sans-concepts, this r=
equirement is implicit. If you template needs to "convert" from one type to=
another, we have an acceptable syntax to do that:<br><br>T1 t1 =3D t2;<br>=
<br>There are no performance issues with this. There is no "irrelevant logi=
c" needed to make this work. You don't need any special cases. You simply u=
se the language features.<br><br>The user will implement the implicit conve=
rsion in T1 or T2 at their leisure, and your template code will adapt to th=
eir choice. There are no cases for you to consider. So long as the user has=
done their jobs in making T1 and T2, this will work.<br><br>And if they di=
dn't, then they get a compiler error. As they should.<br><br>If you want to=
be nicer to the user (so the conversions don't have to be implicit), you i=
nvoke direct initialization:<br><br>T1 t1(t2);<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_4407_271839878.1425363186987--
------=_Part_4406_69524778.1425363186987--
.
Author: zijiehe@google.com
Date: Tue, 3 Mar 2015 06:55:20 -0800 (PST)
Raw View
------=_Part_144_1112565195.1425394520489
Content-Type: multipart/alternative;
boundary="----=_Part_145_743117936.1425394520489"
------=_Part_145_743117936.1425394520489
Content-Type: text/plain; charset=UTF-8
Sorry, do you really mean c2 = 1; does not use operator=(int)?
And I still cannot quite understand, why you think implicit constructor and
operator= are the same thing. They are definitely two different functions,
while C c = 1; uses implicit constructor, C c; c = 1; uses operator=. A
class may implement one of them or both, or none. Some school books
mentioned that you always should implement operator= (const T&) with
T(const T&), but the compiler does not force you to do so.
On Tuesday, March 3, 2015 at 2:13:07 PM UTC+8, Nicol Bolas wrote:
>
>
>
> On Monday, March 2, 2015 at 9:28:25 PM UTC-5, Zijie He wrote:
>>
>> The proposal is targeting three different problems,
>> 1. is_assignable is much more than T1 t1 = t2;
>>
>
> Actually, that's line is not an example of is_assignable at all. That
> statement will never use the assignment operator; it will instead use an
> appropriate conversion (either via an implicit constructor or via a single
> implicit conversion operator call).
>
>
>> 2. As you have mentioned, performance concern. There may be several ways
>> to convert from T1 to T2, while this implementation can help to select the
>> best one.
>>
>
> As previously stated, the only performance concern as things currently
> stand is the rare case of performing a conversion into a live object. And
> you have yet to explain why this case is important enough to bother with
> such a change.
>
>
>> 3. Typically in template programming, usually you do not know the types
>> of T1 and T2, while there may be several ways to convert from T1 to T2.
>>
>
> There are not "several" ways to convert; there are precisely two: either
> via initialization of a new value or via copy/move-into-a-live-object. Both
> ways in C++ use the assignment operator (though the initialization case
> doesn't call the overload for it). The language supports these cases well
> enough without template metaprogramming or 'convert_to' or other such stuff.
>
> So what are these "several ways" you keep talking about optimizing for?
> What are the other alternatives?
>
> Several types may implements constructor, several types may implements
>> operator=. The behavior will be same, but in the template, you may need to
>> handle several cases. So this implementation is to separate the irrelevant
>> logic from this kind of templates.
>>
>
> Nonsense. In a template, you impose some particular requirement on the
> type. Sans-concepts, this requirement is implicit. If you template needs to
> "convert" from one type to another, we have an acceptable syntax to do that:
>
> T1 t1 = t2;
>
> There are no performance issues with this. There is no "irrelevant logic"
> needed to make this work. You don't need any special cases. You simply use
> the language features.
>
> The user will implement the implicit conversion in T1 or T2 at their
> leisure, and your template code will adapt to their choice. There are no
> cases for you to consider. So long as the user has done their jobs in
> making T1 and T2, this will work.
>
> And if they didn't, then they get a compiler error. As they should.
>
> If you want to be nicer to the user (so the conversions don't have to be
> implicit), you invoke direct initialization:
>
> T1 t1(t2);
>
--
---
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_145_743117936.1425394520489
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Sorry, do you really mean c2 =3D 1; does not use operator=
=3D(int)?<div>And I still cannot quite understand, why you think implicit c=
onstructor and operator=3D are the same thing. They are definitely two diff=
erent functions, while C c =3D 1; uses implicit constructor, C c; c =3D 1; =
uses operator=3D. A class may implement one of them or both, or none. Some =
school books mentioned that you always should implement operator=3D (const =
T&) with T(const T&), but the compiler does not force you to do so.=
</div><div><br></div><div>On Tuesday, March 3, 2015 at 2:13:07 PM UTC+8, Ni=
col Bolas 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"lt=
r"><br><br>On Monday, March 2, 2015 at 9:28:25 PM UTC-5, Zijie He wrote:<bl=
ockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-l=
eft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">The proposal is targe=
ting three different problems,<div>1. is_assignable is much more than T1 t1=
=3D t2;</div></div></blockquote><div><br>Actually, that's line is not an e=
xample of is_assignable at all. That statement will never use
the assignment operator; it will instead use an appropriate conversion (ei=
ther via an implicit constructor or via a single implicit conversion operat=
or call).<br> </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">2. As you have mentioned, performance concern. There may be severa=
l ways to convert from T1 to T2, while this implementation can help to sele=
ct the best one.<br></div></blockquote><div><br>As previously stated, the o=
nly performance concern as things currently stand is the rare case of perfo=
rming a conversion into a live object. And you have yet to explain why this=
case is important enough to bother with such a change.<br> </div><blo=
ckquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-le=
ft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>3. Typically in t=
emplate programming, usually you do not know the types of T1 and T2, while =
there may be several ways to convert from T1 to T2.</div></div></blockquote=
><div><br>There are not "several" ways to convert; there are precisely two:=
either via initialization of a new value or via copy/move-into-a-live-obje=
ct. Both ways in C++ use the assignment operator (though the initialization=
case doesn't call the overload for it). The language supports these cases =
well enough without template metaprogramming or 'convert_to' or other such =
stuff.<br><br>So what are these "several ways" you keep talking about optim=
izing for? What are the other alternatives?<br><br></div><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr"><div>Several types may implements c=
onstructor, several types may implements operator=3D. The behavior will be =
same, but in the template, you may need to handle several cases. So this im=
plementation is to separate the irrelevant logic from this kind of template=
s.<br></div></div></blockquote><div><br>Nonsense. In a template, you impose=
some particular requirement on the type. Sans-concepts, this requirement i=
s implicit. If you template needs to "convert" from one type to another, we=
have an acceptable syntax to do that:<br><br>T1 t1 =3D t2;<br><br>There ar=
e no performance issues with this. There is no "irrelevant logic" needed to=
make this work. You don't need any special cases. You simply use the langu=
age features.<br><br>The user will implement the implicit conversion in T1 =
or T2 at their leisure, and your template code will adapt to their choice. =
There are no cases for you to consider. So long as the user has done their =
jobs in making T1 and T2, this will work.<br><br>And if they didn't, then t=
hey get a compiler error. As they should.<br><br>If you want to be nicer to=
the user (so the conversions don't have to be implicit), you invoke direct=
initialization:<br><br>T1 t1(t2);<br></div></div></blockquote></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_145_743117936.1425394520489--
------=_Part_144_1112565195.1425394520489--
.
Author: Zijie He <hzj_jie@hotmail.com>
Date: Tue, 3 Mar 2015 06:58:16 -0800 (PST)
Raw View
------=_Part_70_2024141473.1425394696839
Content-Type: multipart/alternative;
boundary="----=_Part_71_1457284584.1425394696839"
------=_Part_71_1457284584.1425394696839
Content-Type: text/plain; charset=UTF-8
Sorry, do you really mean c2 = 1; does not use operator=(int)? If there is
a conversion operator, it will be used, but in the case I have provided,
the operator= is definitely involved.
And I still cannot quite understand, why you think implicit constructor and
operator= are the same thing. They are two different functions, while C c =
1; uses implicit constructor, C c; c = 1; uses operator=. A class may
implement one of them or both, or none. Some school books mentioned that
you always should implement operator= (const T&) with T(const T&), but the
compiler does not force you to do so.
On Tuesday, March 3, 2015 at 2:13:07 PM UTC+8, Nicol Bolas wrote:
>
>
>
> On Monday, March 2, 2015 at 9:28:25 PM UTC-5, Zijie He wrote:
>>
>> The proposal is targeting three different problems,
>> 1. is_assignable is much more than T1 t1 = t2;
>>
>
> Actually, that's line is not an example of is_assignable at all. That
> statement will never use the assignment operator; it will instead use an
> appropriate conversion (either via an implicit constructor or via a single
> implicit conversion operator call).
>
>
>> 2. As you have mentioned, performance concern. There may be several ways
>> to convert from T1 to T2, while this implementation can help to select the
>> best one.
>>
>
> As previously stated, the only performance concern as things currently
> stand is the rare case of performing a conversion into a live object. And
> you have yet to explain why this case is important enough to bother with
> such a change.
>
>
>> 3. Typically in template programming, usually you do not know the types
>> of T1 and T2, while there may be several ways to convert from T1 to T2.
>>
>
> There are not "several" ways to convert; there are precisely two: either
> via initialization of a new value or via copy/move-into-a-live-object. Both
> ways in C++ use the assignment operator (though the initialization case
> doesn't call the overload for it). The language supports these cases well
> enough without template metaprogramming or 'convert_to' or other such stuff.
>
> So what are these "several ways" you keep talking about optimizing for?
> What are the other alternatives?
>
> Several types may implements constructor, several types may implements
>> operator=. The behavior will be same, but in the template, you may need to
>> handle several cases. So this implementation is to separate the irrelevant
>> logic from this kind of templates.
>>
>
> Nonsense. In a template, you impose some particular requirement on the
> type. Sans-concepts, this requirement is implicit. If you template needs to
> "convert" from one type to another, we have an acceptable syntax to do that:
>
> T1 t1 = t2;
>
> There are no performance issues with this. There is no "irrelevant logic"
> needed to make this work. You don't need any special cases. You simply use
> the language features.
>
> The user will implement the implicit conversion in T1 or T2 at their
> leisure, and your template code will adapt to their choice. There are no
> cases for you to consider. So long as the user has done their jobs in
> making T1 and T2, this will work.
>
> And if they didn't, then they get a compiler error. As they should.
>
> If you want to be nicer to the user (so the conversions don't have to be
> implicit), you invoke direct initialization:
>
> T1 t1(t2);
>
--
---
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_71_1457284584.1425394696839
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Sorry, do you really mean c2 =3D 1; does not use operator=
=3D(int)? If there is a conversion operator, it will be used, but in the ca=
se I have provided, the operator=3D is definitely involved.<div>And I still=
cannot quite understand, why you think implicit constructor and operator=
=3D are the same thing. They are two different functions, while C c =3D 1; =
uses implicit constructor, C c; c =3D 1; uses operator=3D. A class may impl=
ement one of them or both, or none. Some school books mentioned that you al=
ways should implement operator=3D (const T&) with T(const T&), but =
the compiler does not force you to do so.</div><br>On Tuesday, March 3, 201=
5 at 2:13:07 PM UTC+8, Nicol Bolas wrote:<blockquote class=3D"gmail_quote" =
style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-l=
eft: 1ex;"><div dir=3D"ltr"><br><br>On Monday, March 2, 2015 at 9:28:25 PM =
UTC-5, Zijie He wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;m=
argin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"l=
tr">The proposal is targeting three different problems,<div>1. is_assignabl=
e is much more than T1 t1 =3D t2;</div></div></blockquote><div><br>Actually=
, that's line is not an example of is_assignable at all. That statement wil=
l never use
the assignment operator; it will instead use an appropriate conversion (ei=
ther via an implicit constructor or via a single implicit conversion operat=
or call).<br> </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">2. As you have mentioned, performance concern. There may be severa=
l ways to convert from T1 to T2, while this implementation can help to sele=
ct the best one.<br></div></blockquote><div><br>As previously stated, the o=
nly performance concern as things currently stand is the rare case of perfo=
rming a conversion into a live object. And you have yet to explain why this=
case is important enough to bother with such a change.<br> </div><blo=
ckquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-le=
ft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>3. Typically in t=
emplate programming, usually you do not know the types of T1 and T2, while =
there may be several ways to convert from T1 to T2.</div></div></blockquote=
><div><br>There are not "several" ways to convert; there are precisely two:=
either via initialization of a new value or via copy/move-into-a-live-obje=
ct. Both ways in C++ use the assignment operator (though the initialization=
case doesn't call the overload for it). The language supports these cases =
well enough without template metaprogramming or 'convert_to' or other such =
stuff.<br><br>So what are these "several ways" you keep talking about optim=
izing for? What are the other alternatives?<br><br></div><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr"><div>Several types may implements c=
onstructor, several types may implements operator=3D. The behavior will be =
same, but in the template, you may need to handle several cases. So this im=
plementation is to separate the irrelevant logic from this kind of template=
s.<br></div></div></blockquote><div><br>Nonsense. In a template, you impose=
some particular requirement on the type. Sans-concepts, this requirement i=
s implicit. If you template needs to "convert" from one type to another, we=
have an acceptable syntax to do that:<br><br>T1 t1 =3D t2;<br><br>There ar=
e no performance issues with this. There is no "irrelevant logic" needed to=
make this work. You don't need any special cases. You simply use the langu=
age features.<br><br>The user will implement the implicit conversion in T1 =
or T2 at their leisure, and your template code will adapt to their choice. =
There are no cases for you to consider. So long as the user has done their =
jobs in making T1 and T2, this will work.<br><br>And if they didn't, then t=
hey get a compiler error. As they should.<br><br>If you want to be nicer to=
the user (so the conversions don't have to be implicit), you invoke direct=
initialization:<br><br>T1 t1(t2);<br></div></div></blockquote></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_71_1457284584.1425394696839--
------=_Part_70_2024141473.1425394696839--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 3 Mar 2015 17:14:25 -0800 (PST)
Raw View
------=_Part_1248_966119045.1425431665817
Content-Type: multipart/alternative;
boundary="----=_Part_1249_438934348.1425431665817"
------=_Part_1249_438934348.1425431665817
Content-Type: text/plain; charset=UTF-8
On Tuesday, March 3, 2015 at 9:58:16 AM UTC-5, Zijie He wrote:
>
> Sorry, do you really mean c2 = 1; does not use operator=(int)? If there is
> a conversion operator, it will be used, but in the case I have provided,
> the operator= is definitely involved.
>
And I still cannot quite understand, why you think implicit constructor and
> operator= are the same thing. They are two different functions, while C c =
> 1; uses implicit constructor, C c; c = 1; uses operator=.
>
Yes, and those are the *only two* cases involved. There are not "several";
just two. And C++ handles both of them.
So what exactly is the point of this alternate method? What problem is it
trying to solve? Your example code didn't explain this very clearly.
Show me a case that C++ can't handle currently (or handles inefficiently).
--
---
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_1249_438934348.1425431665817
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Tuesday, March 3, 2015 at 9:58:16 AM UTC-5, Zij=
ie He wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div>Sorry, do you=
really mean c2 =3D 1; does not use operator=3D(int)? If there is a convers=
ion operator, it will be used, but in the case I have provided, the operato=
r=3D is definitely involved. </div></blockquote><blockquote class=3D"gmail_=
quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;pa=
dding-left: 1ex;"><div dir=3D"ltr"><div>And I still cannot quite understand=
, why you think implicit constructor and operator=3D are the same thing. Th=
ey are two different functions, while C c =3D 1; uses implicit constructor,=
C c; c =3D 1; uses operator=3D.</div></div></blockquote><div><br>Yes, and =
those are the <i>only two</i> cases involved. There are not "several"; just=
two. And C++ handles both of them.<br><br>So what exactly is the point of =
this alternate method? What problem is it trying to solve? Your example cod=
e didn't explain this very clearly.<br><br>Show me a case that C++ can't ha=
ndle currently (or handles inefficiently).<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_1249_438934348.1425431665817--
------=_Part_1248_966119045.1425431665817--
.
Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
Date: Tue, 3 Mar 2015 17:48:47 -0800 (PST)
Raw View
------=_Part_3533_1146879797.1425433727079
Content-Type: multipart/alternative;
boundary="----=_Part_3534_1943016354.1425433727079"
------=_Part_3534_1943016354.1425433727079
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Tuesday, March 3, 2015 at 5:14:25 PM UTC-8, Nicol Bolas wrote:
>
> On Tuesday, March 3, 2015 at 9:58:16 AM UTC-5, Zijie He wrote:
>>
>> Sorry, do you really mean c2 =3D 1; does not use operator=3D(int)? If th=
ere=20
>> is a conversion operator, it will be used, but in the case I have provid=
ed,=20
>> the operator=3D is definitely involved.=20
>>
> And I still cannot quite understand, why you think implicit constructor=
=20
>> and operator=3D are the same thing. They are two different functions, wh=
ile C=20
>> c =3D 1; uses implicit constructor, C c; c =3D 1; uses operator=3D.
>>
>
> Yes, and those are the *only two* cases involved. There are not=20
> "several"; just two. And C++ handles both of them.
>
> So what exactly is the point of this alternate method? What problem is it=
=20
> trying to solve? Your example code didn't explain this very clearly.
>
> Show me a case that C++ can't handle currently (or handles inefficiently)=
..
>
Zijie's code has at least one case where it does something "more=20
efficiently" than the standard C++ way of doing things.
struct copy_constructible
{
template <typename T1, typename T2>
static bool copy(const T1& i, T2& o)
{
new (&o) T2(i);
return true;
}
};
=20
However, this will (in practice) invoke undefined behavior, since the old=
=20
value of o is not properly destructed before a new one is constructed over=
=20
top of it. The only way to use Zijie's code safely is to pass in a pointer=
=20
to uninitialized memory that you've somehow casted to a T2&. (This is=20
possible, of course, but in practice it's something that nobody does and=20
nobody should do.)
Zijie's code is a neat bit of metaprogramming, but it's not even the=20
simplest way to get the behavior he wants.
http://melpon.org/wandbox/permlink/1txESplvRH4TrvAS
template<class T, class U>
bool copy_(T&&, U&&, int) { return false; }
template<class T, class U>
auto copy_(T&& t, U&& u, bool) -> decltype(std::forward<U>(u) =3D std::forw=
ard
<T>(t), true) { std::forward<U>(u) =3D std::forward<T>(t); return true; }
template<class T, class U>
auto copy(T&& t, U&& u) { return copy_(std::forward<T>(t), std::forward<U>(=
u
), true); }
int main() {
int i; std::string s;
assert(copy("x", s) =3D=3D true);=20
assert(copy(s, s) =3D=3D true);
assert(copy(s, "x") =3D=3D false);=20
assert(copy(s, i) =3D=3D false);
assert(copy(0, i) =3D=3D true);
assert(copy(i, 0) =3D=3D false);
}
This doesn't preserve the "undefined behavior on copy-construct into=20
undestroyed object", but you could certainly add that behavior back in if=
=20
you really wanted it.
I don't see anything here that deserves inclusion in a standard library.
=E2=80=93Arthur
--=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_3534_1943016354.1425433727079
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Tuesday, March 3, 2015 at 5:14:25 PM UTC-8, Nic=
ol Bolas 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=
">On Tuesday, March 3, 2015 at 9:58:16 AM UTC-5, Zijie He wrote:<blockquote=
class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px =
#ccc solid;padding-left:1ex"><div>Sorry, do you really mean c2 =3D 1; does =
not use operator=3D(int)? If there is a conversion operator, it will be use=
d, but in the case I have provided, the operator=3D is definitely involved.=
</div></blockquote><blockquote class=3D"gmail_quote" style=3D"margin:0;mar=
gin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr=
"><div>And I still cannot quite understand, why you think implicit construc=
tor and operator=3D are the same thing. They are two different functions, w=
hile C c =3D 1; uses implicit constructor, C c; c =3D 1; uses operator=3D.<=
/div></div></blockquote><div><br>Yes, and those are the <i>only two</i> cas=
es involved. There are not "several"; just two. And C++ handles both of the=
m.<br><br>So what exactly is the point of this alternate method? What probl=
em is it trying to solve? Your example code didn't explain this very clearl=
y.<br><br>Show me a case that C++ can't handle currently (or handles ineffi=
ciently).<br></div></div></blockquote><div><br></div><div>Zijie's code has =
at least one case where it does something "more efficiently" than the stand=
ard C++ way of doing things.</div><div><br></div><div style=3D"color: rgb(1=
02, 0, 102); font-family: monospace;"> struct copy_constructib=
le</div><div style=3D"color: rgb(102, 0, 102); font-family: monospace;">&nb=
sp; {</div><div style=3D"color: rgb(102, 0, 102); font-family: monos=
pace;"> template <typename T1, typename T2>=
;</div><div style=3D"color: rgb(102, 0, 102); font-family: monospace;">&nbs=
p; static bool copy(const T1& i, T2& o)</div><=
div style=3D"color: rgb(102, 0, 102); font-family: monospace;">  =
; {</div><div style=3D"color: rgb(102, 0, 102); font-family: =
monospace;"> new (&o) T2(i);</=
div><div style=3D"color: rgb(102, 0, 102); font-family: monospace;"> =
return true;</div><div style=3D"color: r=
gb(102, 0, 102); font-family: monospace;"> }</di=
v><div><span style=3D"color: rgb(102, 0, 102); font-family: monospace;">&nb=
sp; };</span></div><div> </div><div>However, this will (in prac=
tice) invoke undefined behavior, since the old value of <font face=3D"couri=
er new, monospace">o</font> is not properly destructed before a new one is =
constructed over top of it. The only way to use Zijie's code safely is to p=
ass in a pointer to uninitialized memory that you've somehow casted to=
a <font face=3D"courier new, monospace">T2&</font>. (This is possible,=
of course, but in practice it's something that nobody does and nobody shou=
ld do.)</div><div><br></div><div>Zijie's code is a neat bit of metaprogramm=
ing, but it's not even the simplest way to get the behavior he wants.</div>=
<div><br></div><div>http://melpon.org/wandbox/permlink/1txESplvRH4TrvAS<br>=
</div><div><br></div><div class=3D"prettyprint" style=3D"background-color: =
rgb(250, 250, 250); border: 1px solid rgb(187, 187, 187); word-wrap: break-=
word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">template</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify"><</span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">class</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> T</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-=
prettify">class</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> U</span><span style=3D"color: #660;" class=3D"styled-by-prettify">>=
;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">bool</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> copy_</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify">T</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">&&,</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> U</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">&&,</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"sty=
led-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"=
> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=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=
: #008;" class=3D"styled-by-prettify">false</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </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><br></span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">template</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
"><</span><span style=3D"color: #008;" class=3D"styled-by-prettify">clas=
s</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> T</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">class</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> U</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: #008;" class=3D"style=
d-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> copy_</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">T</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">&&</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 style=
=3D"color: #000;" class=3D"styled-by-prettify"> U</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">&&</span><span style=3D"colo=
r: #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: #008;" class=3D"style=
d-by-prettify">bool</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
</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: #008;" class=3D"styled-by-prettify">decltype</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"co=
lor: #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">forward</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify"><</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify">U</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">>(</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy">u</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: #660;" class=3D"styled-by-prettify">=3D</span><span style=
=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">forward</span><span style=3D"color: #660;"=
class=3D"styled-by-prettify"><</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">T</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">>(</span><span style=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: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">true</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;" 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">forward</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify"><</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y">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><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=
: #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;" clas=
s=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify">forward</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify"><</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">T</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&=
gt;(</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"> </span><span style=3D"=
color: #008;" class=3D"styled-by-prettify">return</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;"=
class=3D"styled-by-prettify">true</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=
><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">templ=
ate</span><span style=3D"color: #660;" class=3D"styled-by-prettify"><</s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">class</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> T</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: #008;=
" class=3D"styled-by-prettify">class</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> U</span><span style=3D"color: #660;" class=3D"st=
yled-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">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
copy</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span style=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: #000;" class=3D"styled-by-prettify"> t</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;" cl=
ass=3D"styled-by-prettify">&&</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> u</span><span style=3D"color: #660;" class=3D"s=
tyled-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"> </span>=
<span style=3D"color: #008;" class=3D"styled-by-prettify">return</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> copy_</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"co=
lor: #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">forward</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify"><</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify">T</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">>(</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy">t</span><span style=3D"color: #660;" class=3D"styled-by-prettify">),</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> std</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">forward</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify"><</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify">U</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">>(</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify">u</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">),</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>true</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><br></span><span style=3D"c=
olor: #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;"=
class=3D"styled-by-prettify">()</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </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: #008;" class=3D"styled=
-by-prettify">int</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> i</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 s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">string</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> s</span><span style=3D"colo=
r: #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">assert</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">copy</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">(</span><span style=3D"color: #080;" class=3D"styled-by-=
prettify">"x"</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> s</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: #660;" class=3D"styled-by-prettify">=3D=3D</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;"=
class=3D"styled-by-prettify">true</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> <br> </span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">assert</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify">copy</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">s</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><spa=
n 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"> </span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">=3D=3D</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">true</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">assert</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">cop=
y</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify">s</span><span styl=
e=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: #080;"=
class=3D"styled-by-prettify">"x"</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=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">false</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> <br> <=
/span><span style=3D"color: #008;" class=3D"styled-by-prettify">assert</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">copy</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</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"> i</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">false</span><span s=
tyle=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">assert</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">copy</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"style=
d-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> i</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: #660;" class=3D"styled-by-prettify">=3D=3D</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">true</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br> </span><span style=3D"color: =
#008;" class=3D"styled-by-prettify">assert</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">copy</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify">i</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">0</span><span styl=
e=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=3D</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">false</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">}<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span>=
</div></code></div><div><br></div><div>This doesn't preserve the "undefined=
behavior on copy-construct into undestroyed object", but you could certain=
ly add that behavior back in if you really wanted it.</div><div>I don't see=
anything here that deserves inclusion in a standard library.</div><div><br=
>=E2=80=93Arthur</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_3534_1943016354.1425433727079--
------=_Part_3533_1146879797.1425433727079--
.