Topic: Potential issue with N4174 - Uniform call syntax


Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Thu, 9 Jul 2015 10:57:09 -0700 (PDT)
Raw View
------=_Part_1199_1718255352.1436464629771
Content-Type: multipart/alternative;
 boundary="----=_Part_1200_533704616.1436464629771"

------=_Part_1200_533704616.1436464629771
Content-Type: text/plain; charset=UTF-8

Suppose I want to test whether or not a given type defines a member
function. Such a construct usually starts with an expression like this:

//Test if type T has a member function foo().
decltype(declval<T>().foo())

With N4174, if someone defines a free function foo(T), this construct will
be well formed but may not do what the user expected. The semantics change
from "tell me if T has a member function foo()" to "tell me if T has a
member function foo() or a free function foo(T) exists". For some uses
cases, this might be ok but for others it will break.

For an example of something that would be broken by N4174, see my other
thread about non-member cbegin() which tests for member cbegin()
and returns that if it exists, otherwise performs a default action.



--

---
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_1200_533704616.1436464629771
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Suppose I want to test whether or not a given type=C2=
=A0defines a member function. Such a construct usually starts with an expre=
ssion like this:</div><div>=C2=A0</div><div><div style=3D"border: 1px solid=
 rgb(187, 187, 187); word-wrap: break-word; background-color: rgb(250, 250,=
 250);" class=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"sub=
prettyprint"><span style=3D"color: rgb(136, 0, 0);" class=3D"styled-by-pret=
tify">//Test if type T has a member function foo().</span><span style=3D"co=
lor: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br></span><span style=3D"=
color: rgb(0, 0, 136);" class=3D"styled-by-prettify">decltype</span><span s=
tyle=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">(</span><spa=
n style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify">declval</span=
><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">&lt;=
</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify">T<=
/span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify"=
>&gt;().</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-pret=
tify">foo</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by=
-prettify">())</span></div></code></div><br>With N4174, if someone defines =
a free function foo(T), this construct will be well formed but may not do w=
hat the user expected.=C2=A0The semantics=C2=A0change from &quot;tell me if=
 T has a member function foo()&quot; to &quot;tell me if T has a member fun=
ction foo() or a free function foo(T) exists&quot;. For some uses cases, th=
is might be ok but for others it will break.</div><div>=C2=A0</div><div>For=
 an example of something that would be broken by N4174, see my other thread=
 about non-member cbegin() which tests for member cbegin() and=C2=A0returns=
 that if it exists, otherwise performs a default action.</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&quot; 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_1200_533704616.1436464629771--
------=_Part_1199_1718255352.1436464629771--

.


Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Thu, 9 Jul 2015 12:34:32 -0700 (PDT)
Raw View
------=_Part_898_1641736398.1436470472235
Content-Type: multipart/alternative;
 boundary="----=_Part_899_1790884848.1436470472236"

------=_Part_899_1790884848.1436470472236
Content-Type: text/plain; charset=UTF-8


On Thursday, July 9, 2015 at 1:57:09 PM UTC-4, Matthew Fioravante wrote:
>
> Suppose I want to test whether or not a given type defines a member
> function. Such a construct usually starts with an expression like this:
>
> //Test if type T has a member function foo().
> decltype(declval<T>().foo())
>
> With N4174, if someone defines a free function foo(T), this construct will
> be well formed but may not do what the user expected. The semantics change
> from "tell me if T has a member function foo()" to "tell me if T has a
> member function foo() or a free function foo(T) exists". For some uses
> cases, this might be ok but for others it will break.
>
> For an example of something that would be broken by N4174, see my other
> thread about non-member cbegin() which tests for member cbegin()
> and returns that if it exists, otherwise performs a default action.
>
>

Even more fun is that for my cbegin(), if N4174 was accepted then cbegin()
would test for itself and then call itself in an infinite loop with no
compiler diagnostics.

What are the major use cases N4174? Can they be satisfied in other ways? It
seems that it would be confusing to me to see a call to a function and not
knowing exactly whether its a member or a free function being called when
I'm trying to read and understand a piece of code. This is like optimizing
for the code writer at the expense of the reader.

Maybe defining a free function with the same name in std:: that has the
idiom of "call the member if it exists, or do the default action" is
sufficient for many cases?

For example lets consider swap. The current situation with swap is a huge
confusing mess. Common questions are: Do I define non-member swap
specialization in std::, non-member in my namespace, as a member? Actually
myself I've yet to learn what the correct approach is and goodluck teaching
it to newbies. Also the need to add "using std::swap;" into your swap
implementation is just plain horrible. Easy to forget for advanced
developers and painful for novices when you have to explain ADL as the
reason why. This is a wonderful piece of ammo for the "C++ is for experts
only" crowd.

If I were designing swap today, I'd do it this way:

std::swap(T& l, T& r) would be defined as "call l.swap(r) if thats a valid
expression, otherwise emulate swapping using moves and a temporary (or
copies if not movable)" with conditional constexpr and noexcept if the
underlying operations are such.

For most types, I'd wager that modern optimizers are good enough that the
default action of moving into a temporary is perfectly fine so they don't
need to define a swap member. If your type is such that the default way of
swapping is not efficient, then you define a member swap() as an
optimization. If you need to define a member swap(), then most likely you
need to mess with the private implementation details of your class (data
members), and therefore a member function is more appropriate than a
non-member function. With this approach, the need to say "using std::swap;"
and all of the ADL baggage goes away. All of the swap specializations for
the std containers can be removed too as the default will just call the
members.



--

---
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_899_1790884848.1436470472236
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<br>On Thursday, July 9, 2015 at 1:57:09 PM UTC-4, Matthew Fioravante wrote=
:<blockquote style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-=
left-color: rgb(204, 204, 204); border-left-width: 1px; border-left-style: =
solid;" class=3D"gmail_quote"><div dir=3D"ltr"><div>Suppose I want to test =
whether or not a given type=C2=A0defines a member function. Such a construc=
t usually starts with an expression like this:</div><div>=C2=A0</div><div><=
div style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-word; b=
ackground-color: rgb(250, 250, 250);"><code><div><span style=3D"color: rgb(=
136, 0, 0);">//Test if type T has a member function foo().</span><span styl=
e=3D"color: rgb(0, 0, 0);"><br></span><span style=3D"color: rgb(0, 0, 136);=
">decltype</span><span style=3D"color: rgb(102, 102, 0);">(</span><span sty=
le=3D"color: rgb(0, 0, 0);">declval</span><span style=3D"color: rgb(102, 10=
2, 0);">&lt;</span><span style=3D"color: rgb(0, 0, 0);">T</span><span style=
=3D"color: rgb(102, 102, 0);">&gt;().</span><span style=3D"color: rgb(0, 0,=
 0);">foo</span><span style=3D"color: rgb(102, 102, 0);">())</span></div></=
code></div><br>With N4174, if someone defines a free function foo(T), this =
construct will be well formed but may not do what the user expected.=C2=A0T=
he semantics=C2=A0change from &quot;tell me if T has a member function foo(=
)&quot; to &quot;tell me if T has a member function foo() or a free functio=
n foo(T) exists&quot;. For some uses cases, this might be ok but for others=
 it will break.</div><div>=C2=A0</div><div>For an example of something that=
 would be broken by N4174, see my other thread about non-member cbegin() wh=
ich tests for member cbegin() and=C2=A0returns that if it exists, otherwise=
 performs a default action.</div><div>=C2=A0</div></div></blockquote><div>=
=C2=A0</div><div>Even more fun=C2=A0is that for my cbegin(), if N4174 was a=
ccepted then cbegin() would test for itself and then call itself in an infi=
nite loop with no compiler diagnostics.</div><div>=C2=A0</div><div>What are=
 the major use cases N4174? Can they be satisfied in other ways? It seems t=
hat it would be=C2=A0confusing to me to see a call to a function and not kn=
owing exactly whether its a member or a free function being called when I&#=
39;m trying to read and understand a piece of code. This is like optimizing=
 for the code writer at the expense of the reader.</div><div><br>Maybe defi=
ning a free function with the same name=C2=A0in std::=C2=A0that=C2=A0has th=
e idiom of &quot;call the=C2=A0member if it exists, or do the default actio=
n&quot; is sufficient for many cases? </div><div>=C2=A0</div><div>For examp=
le lets consider swap. The current situation with swap is a huge confusing =
mess.=C2=A0Common questions are:=C2=A0Do I define non-member swap specializ=
ation=C2=A0in std::, non-member in my namespace, as a member? Actually myse=
lf I&#39;ve yet to learn what the correct=C2=A0approach is and goodluck tea=
ching it to newbies. Also the need to add &quot;using std::swap;&quot; into=
 your swap implementation is just plain horrible. Easy to forget for advanc=
ed developers=C2=A0and painful for novices when you have to explain ADL as =
the reason why. This is a wonderful piece of ammo for the &quot;C++ is for =
experts only&quot; crowd.</div><div>=C2=A0</div><div>If I were designing sw=
ap today, I&#39;d do it this way:</div><div>=C2=A0</div><div>std::swap(T&am=
p; l, T&amp; r)=C2=A0would be defined as &quot;call=C2=A0l.swap(r) if thats=
 a valid expression, otherwise emulate swapping=C2=A0using moves and a temp=
orary (or copies if not movable)&quot; with conditional constexpr and=C2=A0=
noexcept if the underlying operations are such.</div><div>=C2=A0</div><div>=
For=C2=A0most types, I&#39;d wager that=C2=A0modern optimizers=C2=A0are goo=
d enough that the default action of moving into a temporary is perfectly fi=
ne so they don&#39;t need to define a swap member. If your type is such tha=
t the default way of swapping is not efficient, then you define a member sw=
ap() as an optimization. If you need to define a member swap(), then most l=
ikely you need to mess with the private implementation details of your clas=
s (data members), and=C2=A0therefore a member function is more appropriate =
than a non-member function. With this approach, the need to say &quot;using=
 std::swap;&quot; and all of the ADL baggage=C2=A0goes away. All of the swa=
p specializations for the std containers can be removed too as the default =
will just call the members.</div><div>=C2=A0</div><div>=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&quot; 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_899_1790884848.1436470472236--
------=_Part_898_1641736398.1436470472235--

.


Author: =?UTF-8?Q?Klaim_=2D_Jo=C3=ABl_Lamotte?= <mjklaim@gmail.com>
Date: Thu, 9 Jul 2015 21:47:15 +0200
Raw View
--e89a8f643354b68ad2051a76858b
Content-Type: text/plain; charset=UTF-8

On 9 July 2015 at 21:34, Matthew Fioravante <fmatthew5876@gmail.com> wrote:

> Even more fun is that for my cbegin(), if N4174 was accepted then cbegin()
> would test for itself and then call itself in an infinite loop with no
> compiler diagnostics.


No because std::cbegin() would not be called if T had a .cbegin() to begin
with.

--

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

--e89a8f643354b68ad2051a76858b
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><br><div class=3D"gmail_quote">=
On 9 July 2015 at 21:34, Matthew Fioravante <span dir=3D"ltr">&lt;<a href=
=3D"mailto:fmatthew5876@gmail.com" target=3D"_blank">fmatthew5876@gmail.com=
</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">Even more fun=C2=
=A0is that for my cbegin(), if N4174 was accepted then cbegin() would test =
for itself and then call itself in an infinite loop with no compiler diagno=
stics.</blockquote></div><br>No because std::cbegin() would not be called i=
f T had a .cbegin() to begin with.</div><div class=3D"gmail_extra"><br></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&quot; 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 />

--e89a8f643354b68ad2051a76858b--

.


Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Thu, 9 Jul 2015 12:48:51 -0700 (PDT)
Raw View
------=_Part_1404_6745106.1436471331340
Content-Type: multipart/alternative;
 boundary="----=_Part_1405_1362151860.1436471331341"

------=_Part_1405_1362151860.1436471331341
Content-Type: text/plain; charset=UTF-8


On Thursday, July 9, 2015 at 3:34:32 PM UTC-4, Matthew Fioravante wrote:
>
>
> On Thursday, July 9, 2015 at 1:57:09 PM UTC-4, Matthew Fioravante wrote:
>>
>> Suppose I want to test whether or not a given type defines a member
>> function. Such a construct usually starts with an expression like this:
>>
>> //Test if type T has a member function foo().
>> decltype(declval<T>().foo())
>>
>> With N4174, if someone defines a free function foo(T), this construct
>> will be well formed but may not do what the user expected. The
>> semantics change from "tell me if T has a member function foo()" to "tell
>> me if T has a member function foo() or a free function foo(T) exists". For
>> some uses cases, this might be ok but for others it will break.
>>
>> For an example of something that would be broken by N4174, see my other
>> thread about non-member cbegin() which tests for member cbegin()
>> and returns that if it exists, otherwise performs a default action.
>>
>>
>
> Even more fun is that for my cbegin(), if N4174 was accepted then cbegin()
> would test for itself and then call itself in an infinite loop with no
> compiler diagnostics.
>
> What are the major use cases N4174? Can they be satisfied in other ways?
> It seems that it would be confusing to me to see a call to a function and
> not knowing exactly whether its a member or a free function being called
> when I'm trying to read and understand a piece of code. This is like
> optimizing for the code writer at the expense of the reader.
>
> Maybe defining a free function with the same name in std:: that has the
> idiom of "call the member if it exists, or do the default action" is
> sufficient for many cases?
>
> For example lets consider swap. The current situation with swap is a huge
> confusing mess. Common questions are: Do I define non-member swap
> specialization in std::, non-member in my namespace, as a member? Actually
> myself I've yet to learn what the correct approach is and goodluck teaching
> it to newbies. Also the need to add "using std::swap;" into your swap
> implementation is just plain horrible. Easy to forget for advanced
> developers and painful for novices when you have to explain ADL as the
> reason why. This is a wonderful piece of ammo for the "C++ is for experts
> only" crowd.
>
> If I were designing swap today, I'd do it this way:
>
> std::swap(T& l, T& r) would be defined as "call l.swap(r) if thats a valid
> expression, otherwise emulate swapping using moves and a temporary (or
> copies if not movable)" with conditional constexpr and noexcept if the
> underlying operations are such.
>
> For most types, I'd wager that modern optimizers are good enough that the
> default action of moving into a temporary is perfectly fine so they don't
> need to define a swap member. If your type is such that the default way of
> swapping is not efficient, then you define a member swap() as an
> optimization. If you need to define a member swap(), then most likely you
> need to mess with the private implementation details of your class (data
> members), and therefore a member function is more appropriate than a
> non-member function. With this approach, the need to say "using std::swap;"
> and all of the ADL baggage goes away. All of the swap specializations for
> the std containers can be removed too as the default will just call the
> members.
>
>

Swap Example:

//Current situation
template <typename T>
class Container {
  public:
    //Implement swap using member function since thats whats everyone
usually does
    //anyway and we need to access private members (alternative - friend
function)
    void swap(Container<T>& o) {
      using std::swap; //newbie killer, boilerplate
      swap(_t, o._t);
    }
  private:
    T _t;
};

//Stupid boilerplate
template <typename T>
inline void swap(Container<T>& l, Container<T>& r) { l.swap(r); }


//Improved situation
template <typename T>
class Container {
  public:
    //swap member optimization
    void swap(Container<T>& o) {
      //No using boilerplate
      std::swap(_t, o._t);
    }
  private:
    T _t;
};

//No free function boilerplate



--

---
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_1405_1362151860.1436471331341
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<br>On Thursday, July 9, 2015 at 3:34:32 PM UTC-4, Matthew Fioravante wrote=
:<blockquote style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-=
left-color: rgb(204, 204, 204); border-left-width: 1px; border-left-style: =
solid;" class=3D"gmail_quote"><br>On Thursday, July 9, 2015 at 1:57:09 PM U=
TC-4, Matthew Fioravante wrote:<blockquote style=3D"margin: 0px 0px 0px 0.8=
ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); border-left-w=
idth: 1px; border-left-style: solid;" class=3D"gmail_quote"><div dir=3D"ltr=
"><div>Suppose I want to test whether or not a given type=C2=A0defines a me=
mber function. Such a construct usually starts with an expression like this=
:</div><div>=C2=A0</div><div><div style=3D"border: 1px solid rgb(187, 187, =
187); word-wrap: break-word; background-color: rgb(250, 250, 250);"><code><=
div><span style=3D"color: rgb(136, 0, 0);">//Test if type T has a member fu=
nction foo().</span><span style=3D"color: rgb(0, 0, 0);"><br></span><span s=
tyle=3D"color: rgb(0, 0, 136);">decltype</span><span style=3D"color: rgb(10=
2, 102, 0);">(</span><span style=3D"color: rgb(0, 0, 0);">declval</span><sp=
an style=3D"color: rgb(102, 102, 0);">&lt;</span><span style=3D"color: rgb(=
0, 0, 0);">T</span><span style=3D"color: rgb(102, 102, 0);">&gt;().</span><=
span style=3D"color: rgb(0, 0, 0);">foo</span><span style=3D"color: rgb(102=
, 102, 0);">())</span></div></code></div><br>With N4174, if someone defines=
 a free function foo(T), this construct will be well formed but may not do =
what the user expected.=C2=A0The semantics=C2=A0change from &quot;tell me i=
f T has a member function foo()&quot; to &quot;tell me if T has a member fu=
nction foo() or a free function foo(T) exists&quot;. For some uses cases, t=
his might be ok but for others it will break.</div><div>=C2=A0</div><div>Fo=
r an example of something that would be broken by N4174, see my other threa=
d about non-member cbegin() which tests for member cbegin() and=C2=A0return=
s that if it exists, otherwise performs a default action.</div><div>=C2=A0<=
/div></div></blockquote><div>=C2=A0</div><div>Even more fun=C2=A0is that fo=
r my cbegin(), if N4174 was accepted then cbegin() would test for itself an=
d then call itself in an infinite loop with no compiler diagnostics.</div><=
div>=C2=A0</div><div>What are the major use cases N4174? Can they be satisf=
ied in other ways? It seems that it would be=C2=A0confusing to me to see a =
call to a function and not knowing exactly whether its a member or a free f=
unction being called when I&#39;m trying to read and understand a piece of =
code. This is like optimizing for the code writer at the expense of the rea=
der.</div><div><br>Maybe defining a free function with the same name=C2=A0i=
n std::=C2=A0that=C2=A0has the idiom of &quot;call the=C2=A0member if it ex=
ists, or do the default action&quot; is sufficient for many cases? </div><d=
iv>=C2=A0</div><div>For example lets consider swap. The current situation w=
ith swap is a huge confusing mess.=C2=A0Common questions are:=C2=A0Do I def=
ine non-member swap specialization=C2=A0in std::, non-member in my namespac=
e, as a member? Actually myself I&#39;ve yet to learn what the correct=C2=
=A0approach is and goodluck teaching it to newbies. Also the need to add &q=
uot;using std::swap;&quot; into your swap implementation is just plain horr=
ible. Easy to forget for advanced developers=C2=A0and painful for novices w=
hen you have to explain ADL as the reason why. This is a wonderful piece of=
 ammo for the &quot;C++ is for experts only&quot; crowd.</div><div>=C2=A0</=
div><div>If I were designing swap today, I&#39;d do it this way:</div><div>=
=C2=A0</div><div>std::swap(T&amp; l, T&amp; r)=C2=A0would be defined as &qu=
ot;call=C2=A0l.swap(r) if thats a valid expression, otherwise emulate swapp=
ing=C2=A0using moves and a temporary (or copies if not movable)&quot; with =
conditional constexpr and=C2=A0noexcept if the underlying operations are su=
ch.</div><div>=C2=A0</div><div>For=C2=A0most types, I&#39;d wager that=C2=
=A0modern optimizers=C2=A0are good enough that the default action of moving=
 into a temporary is perfectly fine so they don&#39;t need to define a swap=
 member. If your type is such that the default way of swapping is not effic=
ient, then you define a member swap() as an optimization. If you need to de=
fine a member swap(), then most likely you need to mess with the private im=
plementation details of your class (data members), and=C2=A0therefore a mem=
ber function is more appropriate than a non-member function. With this appr=
oach, the need to say &quot;using std::swap;&quot; and all of the ADL bagga=
ge=C2=A0goes away. All of the swap specializations for the std containers c=
an be removed too as the default will just call the members.</div><div>=C2=
=A0</div></blockquote><div>=C2=A0</div><div>Swap Example:</div><div>=C2=A0<=
/div><div><div style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: br=
eak-word; background-color: rgb(250, 250, 250);" class=3D"prettyprint"><cod=
e class=3D"prettyprint"><div class=3D"subprettyprint"><font color=3D"#88000=
0"><span style=3D"color: rgb(136, 0, 0);" class=3D"styled-by-prettify">//Cu=
rrent situation</span></font><span style=3D"color: rgb(0, 0, 0);" class=3D"=
styled-by-prettify"><br></span><span style=3D"color: rgb(0, 0, 136);" class=
=3D"styled-by-prettify">template</span><span style=3D"color: rgb(0, 0, 0);"=
 class=3D"styled-by-prettify"> </span><span style=3D"color: rgb(102, 102, 0=
);" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: rgb(0, 0,=
 136);" class=3D"styled-by-prettify">typename</span><span style=3D"color: r=
gb(0, 0, 0);" class=3D"styled-by-prettify"> T</span><span style=3D"color: r=
gb(102, 102, 0);" class=3D"styled-by-prettify">&gt;</span><span style=3D"co=
lor: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br></span><span style=3D"=
color: rgb(0, 0, 136);" class=3D"styled-by-prettify">class</span><span styl=
e=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><span style=
=3D"color: rgb(102, 0, 102);" class=3D"styled-by-prettify">Container</span>=
<span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><=
span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">{</spa=
n><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br>=C2=
=A0 </span><span style=3D"color: rgb(0, 0, 136);" class=3D"styled-by-pretti=
fy">public</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-b=
y-prettify">:</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by=
-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: rgb(136, 0, 0);" =
class=3D"styled-by-prettify">//Implement swap using member function since t=
hats whats everyone usually does</span><span style=3D"color: rgb(0, 0, 0);"=
 class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color=
: rgb(136, 0, 0);" class=3D"styled-by-prettify">//anyway and we need to acc=
ess private members (alternative - friend function)</span><span style=3D"co=
lor: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><=
span style=3D"color: rgb(0, 0, 136);" class=3D"styled-by-prettify">void</sp=
an><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> swap<=
/span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify"=
>(</span><span style=3D"color: rgb(102, 0, 102);" class=3D"styled-by-pretti=
fy">Container</span><span style=3D"color: rgb(102, 102, 0);" class=3D"style=
d-by-prettify">&lt;</span><span style=3D"color: rgb(0, 0, 0);" class=3D"sty=
led-by-prettify">T</span><span style=3D"color: rgb(102, 102, 0);" class=3D"=
styled-by-prettify">&gt;&amp;</span><span style=3D"color: rgb(0, 0, 0);" cl=
ass=3D"styled-by-prettify"> o</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(102, 102, 0=
);" class=3D"styled-by-prettify">{</span><span style=3D"color: rgb(0, 0, 0)=
;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 </span><span style=
=3D"color: rgb(0, 0, 136);" class=3D"styled-by-prettify">using</span><span =
style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> std</span><spa=
n 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">swap</spa=
n><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"> </s=
pan><span style=3D"color: rgb(136, 0, 0);" class=3D"styled-by-prettify">//n=
ewbie killer, boilerplate</span><span style=3D"color: rgb(0, 0, 0);" class=
=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 swap</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">_t</span><span style=
=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">,</span><span st=
yle=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> o</span><span st=
yle=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">_t</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>=C2=A0=
 =C2=A0 </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-p=
rettify"><br>=C2=A0 </span><span style=3D"color: rgb(0, 0, 136);" class=3D"=
styled-by-prettify">private</span><span style=3D"color: rgb(102, 102, 0);" =
class=3D"styled-by-prettify">:</span><span style=3D"color: rgb(0, 0, 0);" c=
lass=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 T _t</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"><br></span><span style=
=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">};</span><span s=
tyle=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br><br></span><=
span style=3D"color: rgb(136, 0, 0);" class=3D"styled-by-prettify">//Stupid=
 boilerplate</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-=
prettify"><br></span><span style=3D"color: rgb(0, 0, 136);" class=3D"styled=
-by-prettify">template</span><span style=3D"color: rgb(0, 0, 0);" class=3D"=
styled-by-prettify"> </span><span style=3D"color: rgb(102, 102, 0);" class=
=3D"styled-by-prettify">&lt;</span><span style=3D"color: rgb(0, 0, 136);" c=
lass=3D"styled-by-prettify">typename</span><span style=3D"color: rgb(0, 0, =
0);" class=3D"styled-by-prettify"> T</span><span style=3D"color: rgb(102, 1=
02, 0);" class=3D"styled-by-prettify">&gt;</span><span style=3D"color: rgb(=
0, 0, 0);" class=3D"styled-by-prettify"><br></span><span style=3D"color: rg=
b(0, 0, 136);" class=3D"styled-by-prettify">inline</span><span style=3D"col=
or: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: rgb(0, 0, 136);" class=3D"styled-by-prettify">void</span><span style=3D"=
color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> swap</span><span style=
=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">(</span><span st=
yle=3D"color: rgb(102, 0, 102);" class=3D"styled-by-prettify">Container</sp=
an><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">&l=
t;</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify">=
T</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettif=
y">&gt;&amp;</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-=
prettify"> l</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(102, 0, 102);" class=3D"styl=
ed-by-prettify">Container</span><span style=3D"color: rgb(102, 102, 0);" cl=
ass=3D"styled-by-prettify">&lt;</span><span style=3D"color: rgb(0, 0, 0);" =
class=3D"styled-by-prettify">T</span><span style=3D"color: rgb(102, 102, 0)=
;" class=3D"styled-by-prettify">&gt;&amp;</span><span style=3D"color: rgb(0=
, 0, 0);" class=3D"styled-by-prettify"> r</span><span style=3D"color: rgb(1=
02, 102, 0);" class=3D"styled-by-prettify">)</span><span style=3D"color: rg=
b(0, 0, 0);" class=3D"styled-by-prettify"> </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"> l</span><span style=3D"color: =
rgb(102, 102, 0);" class=3D"styled-by-prettify">.</span><span style=3D"colo=
r: rgb(0, 0, 0);" class=3D"styled-by-prettify">swap</span><span style=3D"co=
lor: rgb(102, 102, 0);" class=3D"styled-by-prettify">(</span><span style=3D=
"color: rgb(0, 0, 0);" class=3D"styled-by-prettify">r</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(102, 102, 0);" class=3D"styled-by-prettify">}</span><span st=
yle=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br><br><br></spa=
n><span style=3D"color: rgb(136, 0, 0);" class=3D"styled-by-prettify">//Imp=
roved situation</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-=
by-prettify"><br></span><span style=3D"color: rgb(0, 0, 136);" class=3D"sty=
led-by-prettify">template</span><span style=3D"color: rgb(0, 0, 0);" class=
=3D"styled-by-prettify"> </span><span style=3D"color: rgb(102, 102, 0);" cl=
ass=3D"styled-by-prettify">&lt;</span><span style=3D"color: rgb(0, 0, 136);=
" class=3D"styled-by-prettify">typename</span><span style=3D"color: rgb(0, =
0, 0);" class=3D"styled-by-prettify"> T</span><span style=3D"color: rgb(102=
, 102, 0);" class=3D"styled-by-prettify">&gt;</span><span style=3D"color: r=
gb(0, 0, 0);" class=3D"styled-by-prettify"><br></span><span style=3D"color:=
 rgb(0, 0, 136);" class=3D"styled-by-prettify">class</span><span style=3D"c=
olor: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: rgb(102, 0, 102);" class=3D"styled-by-prettify">Container</span><span =
style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">{</span><spa=
n style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br>=C2=A0 </=
span><span style=3D"color: rgb(0, 0, 136);" class=3D"styled-by-prettify">pu=
blic</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-pret=
tify">:</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prett=
ify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: rgb(136, 0, 0);" class=
=3D"styled-by-prettify">//swap member optimization</span><span style=3D"col=
or: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><s=
pan style=3D"color: rgb(0, 0, 136);" class=3D"styled-by-prettify">void</spa=
n><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> swap</=
span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">=
(</span><span style=3D"color: rgb(102, 0, 102);" class=3D"styled-by-prettif=
y">Container</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled=
-by-prettify">&lt;</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styl=
ed-by-prettify">T</span><span style=3D"color: rgb(102, 102, 0);" class=3D"s=
tyled-by-prettify">&gt;&amp;</span><span style=3D"color: rgb(0, 0, 0);" cla=
ss=3D"styled-by-prettify"> o</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(102, 102, 0)=
;" class=3D"styled-by-prettify">{</span><span style=3D"color: rgb(0, 0, 0);=
" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 </span><span style=
=3D"color: rgb(136, 0, 0);" class=3D"styled-by-prettify">//No using boilerp=
late</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify=
"><br>=C2=A0 =C2=A0 =C2=A0 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">swap</span><span style=3D"color: rgb(102, 1=
02, 0);" class=3D"styled-by-prettify">(</span><span style=3D"color: rgb(0, =
0, 0);" class=3D"styled-by-prettify">_t</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"> o</span><span style=3D"color: rgb(=
102, 102, 0);" class=3D"styled-by-prettify">.</span><span style=3D"color: r=
gb(0, 0, 0);" class=3D"styled-by-prettify">_t</span><span style=3D"color: r=
gb(102, 102, 0);" class=3D"styled-by-prettify">);</span><span style=3D"colo=
r: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><sp=
an 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>=C2=
=A0 </span><span style=3D"color: rgb(0, 0, 136);" class=3D"styled-by-pretti=
fy">private</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-b=
y-prettify"><br>=C2=A0 =C2=A0 T _t</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><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><br></span><span style=3D"colo=
r: rgb(136, 0, 0);" class=3D"styled-by-prettify">//No free function boilerp=
late</span></div></code></div><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&quot; 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_1405_1362151860.1436471331341--
------=_Part_1404_6745106.1436471331340--

.


Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Thu, 9 Jul 2015 12:53:39 -0700 (PDT)
Raw View
------=_Part_1408_1587005825.1436471619909
Content-Type: multipart/alternative;
 boundary="----=_Part_1409_15096362.1436471619909"

------=_Part_1409_15096362.1436471619909
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable


On Thursday, July 9, 2015 at 3:47:16 PM UTC-4, Klaim - Jo=C3=ABl Lamotte wr=
ote:
>
>
> On 9 July 2015 at 21:34, Matthew Fioravante <fmatth...@gmail.com=20
> <javascript:>> wrote:
>
>> Even more fun is that for my cbegin(), if N4174 was accepted then=20
>> cbegin() would test for itself and then call itself in an infinite loop=
=20
>> with no compiler diagnostics.
>
>
> No because std::cbegin() would not be called if T had a .cbegin() to begi=
n=20
> with.
> =20
>
=20
The problem is when T does not define a .cbegin(), which was the whole=20
point of my idea. This is not limited to my cbegin() idea but to anything=
=20
else which uses a similar idiom.
=20
In generic code, the standard practice will be always use std::cbegin()=20
just like C++11 foreach uses std::begin(). It works for all types whether=
=20
or not they define a cbegin(), including C arrays.=20
=20
If type T does not define .cbegin(), N4174 will cause std::cbegin() to=20
sucessfully test for itself using member call syntax and then call itself=
=20
recursively using member call syntax, intending to call the=20
non-existant member function which it erronerously thinks exists and=20
resulting in an infinite loop with no help from the compiler.

--=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_1409_15096362.1436471619909
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<br>On Thursday, July 9, 2015 at 3:47:16 PM UTC-4, Klaim - Jo=C3=ABl Lamott=
e wrote:<blockquote style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; =
border-left-color: rgb(204, 204, 204); border-left-width: 1px; border-left-=
style: solid;" class=3D"gmail_quote"><div dir=3D"ltr"><div><br><div class=
=3D"gmail_quote">On 9 July 2015 at 21:34, Matthew Fioravante <span dir=3D"l=
tr">&lt;<a onmousedown=3D"this.href=3D&#39;javascript:&#39;;return true;" o=
nclick=3D"this.href=3D&#39;javascript:&#39;;return true;" href=3D"javascrip=
t:" rel=3D"nofollow" target=3D"_blank">fmatth...@gmail.com</a>&gt;</span> w=
rote:<br><blockquote style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex;=
 border-left-color: rgb(204, 204, 204); border-left-width: 1px; border-left=
-style: solid;" class=3D"gmail_quote">Even more fun=C2=A0is that for my cbe=
gin(), if N4174 was accepted then cbegin() would test for itself and then c=
all itself in an infinite loop with no compiler diagnostics.</blockquote></=
div><br>No because std::cbegin() would not be called if T had a .cbegin() t=
o begin with.</div><div>=C2=A0</div></div></blockquote><div>=C2=A0</div><di=
v>The problem is when T does not define a .cbegin(), which was the whole po=
int of my idea. This is not limited to my cbegin() idea but to anything els=
e which uses a similar idiom.</div><div>=C2=A0</div><div>In generic code,=
=C2=A0the standard practice=C2=A0will be=C2=A0always=C2=A0use std::cbegin()=
 just like C++11 foreach uses std::begin(). It works for all types=C2=A0whe=
ther or not they define a cbegin(), including=C2=A0C arrays.=C2=A0</div><di=
v>=C2=A0</div><div>If type T does not define .cbegin(), N4174 will cause st=
d::cbegin() to sucessfully test for itself using member call syntax=C2=A0an=
d then call itself recursively=C2=A0using member call syntax, intending to =
call the non-existant=C2=A0member function which it erronerously thinks exi=
sts and resulting in an infinite loop with no help from the compiler.</div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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_1409_15096362.1436471619909--
------=_Part_1408_1587005825.1436471619909--

.


Author: =?UTF-8?Q?Klaim_=2D_Jo=C3=ABl_Lamotte?= <mjklaim@gmail.com>
Date: Thu, 9 Jul 2015 21:54:22 +0200
Raw View
--047d7b66ef3d2dcd4c051a769fda
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

=E2=80=8BBy the way, N4174 have been processed already (with N4165) and res=
ulted in
N4474: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4474.pdf
I was actually answering with this one in mind (which is now the current
version of the proposal).

You might want to read it to be up to date, see if your questions are still
relevant with the current proposal.

--=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/.

--047d7b66ef3d2dcd4c051a769fda
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br>=E2=80=8BBy the way, N4174 have been processed already=
 (with N4165) and resulted in N4474:=C2=A0<a href=3D"http://www.open-std.or=
g/jtc1/sc22/wg21/docs/papers/2015/n4474.pdf">http://www.open-std.org/jtc1/s=
c22/wg21/docs/papers/2015/n4474.pdf</a><div>I was actually answering with t=
his one in mind (which is now the current version of the proposal).<br><div=
><br></div><div>You might want to read it to be up to date, see if your que=
stions are still relevant with the current proposal.</div><div><br></div></=
div><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&quot; 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 />

--047d7b66ef3d2dcd4c051a769fda--

.


Author: =?UTF-8?Q?Klaim_=2D_Jo=C3=ABl_Lamotte?= <mjklaim@gmail.com>
Date: Thu, 9 Jul 2015 22:00:08 +0200
Raw View
--e89a8f643354ca89d1051a76b3f1
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On 9 July 2015 at 21:54, Klaim - Jo=C3=ABl Lamotte <mjklaim@gmail.com> wrot=
e:

>
> =E2=80=8BBy the way, N4174 have been processed already (with N4165) and r=
esulted
> in N4474:
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4474.pdf
> I was actually answering with this one in mind (which is now the current
> version of the proposal).
>
> You might want to read it to be up to date, see if your questions are
> still relevant with the current proposal.
>
>
>

I believe this un-published proposal might be relevant too:
https://ericniebler.github.io/std/wg21/D4381.html

I don't know what happened with this proposal, it is marked as missing in
the publication tables.

--=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/.

--e89a8f643354ca89d1051a76b3f1
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><div class=3D"gmail_quo=
te">On 9 July 2015 at 21:54, Klaim - Jo=C3=ABl Lamotte <span dir=3D"ltr">&l=
t;<a href=3D"mailto:mjklaim@gmail.com" target=3D"_blank">mjklaim@gmail.com<=
/a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:=
0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);=
border-left-style:solid;padding-left:1ex"><div dir=3D"ltr"><br>=E2=80=8BBy =
the way, N4174 have been processed already (with N4165) and resulted in N44=
74:=C2=A0<a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015=
/n4474.pdf" target=3D"_blank">http://www.open-std.org/jtc1/sc22/wg21/docs/p=
apers/2015/n4474.pdf</a><div>I was actually answering with this one in mind=
 (which is now the current version of the proposal).<br><div><br></div><div=
>You might want to read it to be up to date, see if your questions are stil=
l relevant with the current proposal.</div><div><br></div></div><div><br></=
div></div>
</blockquote></div><br></div><div class=3D"gmail_extra"><br></div><div clas=
s=3D"gmail_extra">I believe this un-published proposal might be relevant to=
o:=C2=A0<a href=3D"https://ericniebler.github.io/std/wg21/D4381.html">https=
://ericniebler.github.io/std/wg21/D4381.html</a></div><div class=3D"gmail_e=
xtra"><br></div><div class=3D"gmail_extra">I don&#39;t know what happened w=
ith this proposal, it is marked as missing in the publication tables.</div>=
<div class=3D"gmail_extra"><br></div><div class=3D"gmail_extra"><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&quot; 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 />

--e89a8f643354ca89d1051a76b3f1--

.


Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Thu, 9 Jul 2015 14:53:46 -0700 (PDT)
Raw View
------=_Part_1388_762078785.1436478826597
Content-Type: multipart/alternative;
 boundary="----=_Part_1389_2069203713.1436478826598"

------=_Part_1389_2069203713.1436478826598
Content-Type: text/plain; charset=UTF-8

Thank you for those. Its not so easy to find the latest revisions of papers
when they keep changing numbers.

As I understand it, the 2 major problems those papers are trying to address
are:
1) Concept definitions and generic code have to choose whether to use
member or non-member call syntax causing incompatibilities and confusion.
2) Calling non-member customization points defined in user
namespaces creates problems with ADL lookup and requires very careful use
of using clauses.

I found this quote most interesting:


For every function mentioned in a concept, we must either define it twice
(as a member and a non-member) or make a (semi-arbitrary) decision on which
syntax is to be used.


I think making a decision on which syntax to be used in generic code is a
valid alternative and its not necessarily arbitrary. For fundamental
concept defining "customization points" like std::begin(), concepts and
generic code should always call the non-member functions. By defining these
customization points as free functions the customization point is
documented directly by just existing as a free function in the standard
library .

Instead of users defining overloads, and having to worry about ADL problems
and using clauses, the standard library can just define these customization
points as trivial wrappers around member functions, with overloads for C
arrays and other primitive core language types as needed.

Examples of call member function or illformed/SFINAE if it does not exist
semantics:
- std::begin()
- std::size()
- std::data()

Examples of call member function or do some almost always adequate default
action if not exist semantics:
- std::swap()
- std::cbegin()
- std::rbegin()

This means that in order to "hook" a customization point and enable
concepts, you have to define a member function in your class definition
with the same name. It seems ever since Scott Meyers article "How
Non-Member Functions Improve Encapsulation" came out in year 2000, member
functions have gotten a bad reputation.

One might argue that implementing hooks using member functions introduces
coupling because free functions are by definition "less coupled" than
member functions. However to eliminate the possibility ODR bugs, if you
customize std::size() for your type, you need to do it in the same header
(or module) as your class definition, effectively coupling it with your
class definition anyway. I'm not entirely convinced that just because an
entity exists in the same file on the next line after the closing class
scope vs within the class scope makes it any more or less coupled. A member
function can still be implemented in terms of the classes public interface
to ease implementation burden when the private details change.

Finally, concept customization hooks such as size(), data(), begin(),
end(), etc.. are fundamental properties of a type. They define what
properties exist and by derivation, what concepts the type conforms to. I
would argue that these kinds of fundamental properties of a type belong
within the class definition, not scattered about elsewhere.

Another possible alternative for concept attributes would be to standardize
on member functions and add compiler generated built in member functions to
C arrays and other core language primitive types as needed. Then we may not
need the non-member wrappers at all and again the ADL/using problems
vanish. Aren't those pesky C arrays a big part of why we need non-member
begin(), size(), data() etc.. to begin with?

int a[5] = { 1, 2, 3, 4, 5 };
static_assert(a.size() == 5);
assert(a.data() == a);
assert(*a.begin() == 1);



Another quote:



"This forces the use of

*x.size() *even if *size(x) *is defined for *X*. If *X *is a type we cannot
change, this is a serious problem because adding a member is an intrusive
operation. This is the observation that has pushed STL-inspired libraries
towards the use of free-standing functions."


Admittedly, we cannot add a member function named size() to a legacy type
that cannot be changed for compatibility with concepts. The current
solution would be to add a non-member size() in the same namespace as the
type. Adding a non-virtual member function is not an ABI breaking change on
every platform I know of so if the type cannot be changed, thats probably
because the type comes from a third party library and thus its also very
bad practice to add new free function definitions to that library's
namespace for the same reason its forbidden to add new definitions to
std::. ADL won't work if you add it to your application's namespace so
you're effectively SoL regardless, free functions do not help you here. I'm
not sure what the best solution is in this case. Maybe one can write a
range adapter which implements the concept compatible properties and use
that with the standard algorithms.

When concepts are the defacto standard, it will also be standard practice
for modern C++ libraries to define compatibly named size(), data() etc..
member functions so this problem goes away in the future.

Another example brought up by the paper is sqrt(). I'd argue that this is a
different beast. size(), begin(), and data() are fundamental properties of
a type and thus belong as members. sqrt() is an external computation you
perform on an object and thus makes more sense as a free function. If you
want to concept / SFINAE on the validity of the expression "sqrt(x)" you
can do so just fine without using clauses because external operations like
sqrt() have no "fallback to default behavior by calling std::sqrt()"
semantics like swap() and rbegin().

Finally, we can also look to see how other languages tackle this problem
for inspiration. In python for example, these python standard language and
library attribles such as __iter__(), __eq__(), __len__(), etc.. are all
defined as member functions inside a python class definition. I don't
recall python developers losing sleep over this apparent coupling and lack
of flexibility. Because of the dynamic type system they have to do it this
way.

Curious to know what people think. Looking forward to my agruments being
ripped to shreds! :)

--

---
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_1389_2069203713.1436478826598
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Thank you for those. Its=C2=A0not so easy to find the=
 latest revisions of papers when they keep changing numbers. </div><div>=C2=
=A0</div><div>As I understand it, the 2 major problems those papers are try=
ing to address are:</div><div>1) Concept definitions=C2=A0and generic code =
have to choose whether to use member or non-member call syntax causing inco=
mpatibilities and confusion.</div><div>2) Calling non-member customization =
points defined in user namespaces=C2=A0creates problems with ADL lookup and=
 requires very careful=C2=A0use of=C2=A0using clauses.</div><div>=C2=A0</di=
v><div>I found this quote most interesting:</div><div>=C2=A0</div><font siz=
e=3D"3"><p>For every function mentioned in a concept, we must either define=
 it twice (as a member and a non-member) or <font style=3D"background-color=
: rgb(255, 242, 204);">make a (semi-arbitrary) decision on which syntax is =
to be used.</font> </p><p>=C2=A0</p><div>I think making a decision on which=
 syntax to be=C2=A0used in generic code is a valid alternative=C2=A0and its=
 not necessarily arbitrary. For fundamental concept defining &quot;customiz=
ation points&quot; like std::begin(),=C2=A0concepts and generic code should=
 always call the non-member functions. By defining these customization poin=
ts as free functions=C2=A0the customization point=C2=A0is documented direct=
ly by just existing as a free function in the standard library .</div><div>=
=C2=A0</div><div>Instead of users defining overloads, and having to worry a=
bout ADL problems and using clauses, the standard library can just define t=
hese customization points as=C2=A0trivial wrappers around member functions,=
 with overloads for C arrays and other primitive core language types=C2=A0a=
s needed.</div><div>=C2=A0</div><div>Examples of call member function or=C2=
=A0illformed/SFINAE=C2=A0if it does not exist semantics:</div><div>- std::b=
egin()</div><div>- std::size()</div><div>- std::data()</div><div>=C2=A0</di=
v><div>Examples of call member function or do some almost always adequate d=
efault action if not exist semantics:</div><div>- std::swap()</div><div>- s=
td::cbegin()</div><div>- std::rbegin()</div><div>=C2=A0</div><div>This mean=
s that in order to &quot;hook&quot; a customization point and enable concep=
ts, you have to define=C2=A0a member function in your class definition with=
 the same name. It seems ever since Scott Meyers article &quot;How Non-Memb=
er Functions Improve Encapsulation&quot; came out in year=C2=A02000,=C2=A0m=
ember functions have gotten a bad=C2=A0reputation.</div><div>=C2=A0</div><d=
iv>One might argue that=C2=A0implementing=C2=A0hooks using=C2=A0member func=
tions=C2=A0introduces coupling because free functions are by definition &qu=
ot;less coupled&quot; than member functions. However to=C2=A0eliminate the =
possibility=C2=A0ODR bugs, if you customize std::size() for your type, you =
need to do it in the same header (or module) as your class definition, effe=
ctively coupling it with your class definition anyway. I&#39;m not entirely=
 convinced that just because an entity exists in the same file=C2=A0on the =
next line after the closing=C2=A0class scope vs within the class scope make=
s it any more or less coupled.=C2=A0A member function can still be implemen=
ted in terms of the classes public interface to ease implementation burden =
when the private details change.</div><div>=C2=A0</div><div>Finally, concep=
t customization hooks such as size(), data(), begin(), end(), etc.. are fun=
damental properties of a type. They define what properties exist and by der=
ivation, what concepts the type=C2=A0conforms to. I would argue that these =
kinds of fundamental properties of a type belong within the class definitio=
n, not scattered about elsewhere.</div><div>=C2=A0</div><div>Another possib=
le alternative for concept attributes would be to standardize on member fun=
ctions and add compiler generated built in member functions to C arrays and=
 other core language=C2=A0primitive types=C2=A0as needed. Then we may not n=
eed the non-member wrappers at all and again the ADL/using problems vanish.=
 Aren&#39;t those pesky C arrays a big part of why we need non-member begin=
(), size(), data() etc.. to begin with?</div><div>=C2=A0</div><div style=3D=
"border: 1px solid rgb(187, 187, 187); word-wrap: break-word; background-co=
lor: rgb(250, 250, 250);" class=3D"prettyprint"><code class=3D"prettyprint"=
><div class=3D"subprettyprint"><span style=3D"color: rgb(0, 0, 136);" class=
=3D"styled-by-prettify">int</span><span style=3D"color: rgb(0, 0, 0);" clas=
s=3D"styled-by-prettify"> a</span><span style=3D"color: rgb(102, 102, 0);" =
class=3D"styled-by-prettify">[</span><span style=3D"color: rgb(0, 102, 102)=
;" class=3D"styled-by-prettify">5</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(102, 10=
2, 0);" class=3D"styled-by-prettify">=3D</span><span style=3D"color: rgb(0,=
 0, 0);" class=3D"styled-by-prettify"> </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=
, 102, 102);" class=3D"styled-by-prettify">1</span><span style=3D"color: rg=
b(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, 102, 102);" class=3D"styled-by-prettify">2</span><span style=3D"colo=
r: rgb(102, 102, 0);" class=3D"styled-by-prettify">,</span><span style=3D"c=
olor: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: rgb(0, 102, 102);" class=3D"styled-by-prettify">3</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, 102, 102);" class=3D"styled-by-prettify">4</span><span st=
yle=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, 102, 102);" class=3D"styled-by-prettify">5</span><sp=
an style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><spa=
n 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></spa=
n><span style=3D"color: rgb(0, 0, 136);" class=3D"styled-by-prettify">stati=
c_assert</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-p=
rettify">a</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-b=
y-prettify">.</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by=
-prettify">size</span><span style=3D"color: rgb(102, 102, 0);" class=3D"sty=
led-by-prettify">()</span><span style=3D"color: rgb(0, 0, 0);" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: rgb(102, 102, 0);" class=3D"=
styled-by-prettify">=3D=3D</span><span style=3D"color: rgb(0, 0, 0);" class=
=3D"styled-by-prettify"> </span><span style=3D"color: rgb(0, 102, 102);" cl=
ass=3D"styled-by-prettify">5</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><span style=3D"color: rgb(0, 0, 13=
6);" class=3D"styled-by-prettify">assert</span><span style=3D"color: rgb(10=
2, 102, 0);" class=3D"styled-by-prettify">(</span><span style=3D"color: rgb=
(0, 0, 0);" class=3D"styled-by-prettify">a</span><span style=3D"color: rgb(=
102, 102, 0);" class=3D"styled-by-prettify">.</span><span style=3D"color: r=
gb(0, 0, 0);" class=3D"styled-by-prettify">data</span><span style=3D"color:=
 rgb(102, 102, 0);" class=3D"styled-by-prettify">()</span><span style=3D"co=
lor: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: rgb(102, 102, 0);" class=3D"styled-by-prettify">=3D=3D</span><span styl=
e=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> a</span><span styl=
e=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><spa=
n style=3D"color: rgb(0, 0, 136);" class=3D"styled-by-prettify">assert</spa=
n><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">a</=
span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">=
..</span><span style=3D"color: rgb(0, 0, 136);" class=3D"styled-by-prettify"=
>begin</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-pr=
ettify"> </span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by=
-prettify">=3D=3D</span><span style=3D"color: rgb(0, 0, 0);" class=3D"style=
d-by-prettify"> </span><span style=3D"color: rgb(0, 102, 102);" class=3D"st=
yled-by-prettify">1</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></div></code></div><font size=3D"3"><p>=C2=
=A0<p>Another quote:<p>=C2=A0<p>&quot;This forces the use of </p></font><p>=
<b><font size=3D"3" face=3D"Calibri,Calibri"><font size=3D"3" face=3D"Calib=
ri,Calibri">x.size() </font></font></b><font size=3D"3" face=3D"Calibri,Cal=
ibri"><font size=3D"3" face=3D"Calibri,Calibri"></font></font><font size=3D=
"3">even if </font><b><font size=3D"3" face=3D"Calibri,Calibri"><font size=
=3D"3" face=3D"Calibri,Calibri">size(x) </font></font></b><font size=3D"3" =
face=3D"Calibri,Calibri"><font size=3D"3" face=3D"Calibri,Calibri"></font><=
/font><font size=3D"3">is defined for </font><b><font size=3D"3" face=3D"Ca=
libri,Calibri"><font size=3D"3" face=3D"Calibri,Calibri">X</font></font></b=
><font size=3D"3" face=3D"Calibri,Calibri"><font size=3D"3" face=3D"Calibri=
,Calibri"></font></font><font size=3D"3">. If </font><b><font size=3D"3" fa=
ce=3D"Calibri,Calibri"><font size=3D"3" face=3D"Calibri,Calibri">X </font><=
/font></b><font size=3D"3" face=3D"Calibri,Calibri"><font size=3D"3" face=
=3D"Calibri,Calibri"></font></font><font size=3D"3">is a type we cannot cha=
nge, this is a serious problem because adding a member is an intrusive oper=
ation. This is the observation that has pushed STL-inspired libraries towar=
ds the use of free-standing functions.&quot;</font></p><p><font size=3D"3">=
</font>=C2=A0</p><div>Admittedly,=C2=A0we cannot add=C2=A0a member function=
 named size() to a legacy type that cannot be changed for compatibility wit=
h concepts. The current solution=C2=A0would be=C2=A0to add a non-member siz=
e() in the same namespace as the type. Adding a non-virtual member function=
 is not an ABI breaking change on every platform I know of=C2=A0so if the t=
ype cannot be changed,=C2=A0thats=C2=A0probably because=C2=A0the type comes=
 from a third party library and thus its also=C2=A0very bad practice=C2=A0t=
o add new free function definitions to that library&#39;s namespace for the=
 same reason its=C2=A0forbidden to add new definitions to std::. ADL won&#3=
9;t work if you add it to your application&#39;s namespace so you&#39;re ef=
fectively SoL regardless, free functions do not help you here. I&#39;m not =
sure what the best solution is in this case. Maybe one can write a range ad=
apter which implements the concept compatible properties and use that with =
the standard algorithms.</div><div>=C2=A0</div><div>When concepts are the d=
efacto standard, it will also be standard practice for modern C++ libraries=
 to define compatibly named=C2=A0size(), data() etc.. member functions so t=
his problem goes away in the future.</div><div>=C2=A0</div><div>Another exa=
mple brought up by the paper is sqrt(). I&#39;d argue that this is a differ=
ent beast. size(), begin(), and data() are fundamental properties=C2=A0of a=
 type and thus belong as members. sqrt() is an external=C2=A0computation yo=
u perform on an object and thus makes more sense as a free function. If you=
 want to concept / SFINAE on the validity of the expression &quot;sqrt(x)&q=
uot; you can do so just fine without using clauses because external=C2=A0op=
erations like sqrt() have no &quot;fallback to default behavior=C2=A0by cal=
ling=C2=A0std::sqrt()&quot; semantics like swap() and rbegin().</div><div><=
br>Finally, we can also look to see how other languages tackle this problem=
 for inspiration. In python for example, these=C2=A0python standard languag=
e and library attribles such as __iter__(), __eq__(), __len__(), etc.. are =
all defined as member functions=C2=A0inside a=C2=A0python class definition.=
 I don&#39;t recall python developers losing sleep over this apparent coupl=
ing and lack of flexibility.=C2=A0Because of=C2=A0the dynamic type system t=
hey have to do it this way.</div><div>=C2=A0</div><div>Curious to know what=
 people think. Looking forward to my agruments being ripped to shreds! :)</=
div></font><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&quot; 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_1389_2069203713.1436478826598--
------=_Part_1388_762078785.1436478826597--

.