From: Alberto Ganesh Barbati on
Niels Dekker - no return address ha scritto:
> Alberto Ganesh Barbati wrote:
>> She could easily do that by providing a concept map like this:
>>
>> concept_map std::Swappable<boost::optional<MyType>>
>> {
>> void swap(boost::optional<MyType>& a, boost::optional<MyType>& b)
>> {
>> // implementation here
>> }
>> };
>
> Cool! I guess one would need to change the implementation of the
> boost::optional<T>::swap member function, to directly call your
> std::swap:
>
> void swap( optional & arg )
> {
> // Calling the new C++0x std::swap by Barbati & Mett:
> std::swap(*this, arg);
> }

Hmmm... however if you do so you would force all users of
boost::optional to provide a concept_map, because in absence of a
concept_map, std::swap() would call the swap() member, causing an
endless loop. I believe that the member swap() should just perform the
"default", non-optimal swap. The user is expected to always call
std::swap(), by doing so she would always get the best swap method
available.

Member swap() should be an ingredient of the std::swap() recipe, users
should use the recipe, not the ingredient directly, unless they know
what they're doing. A library component should not implement the
ingredient by calling the recipe itself otherwise all we get is a
minestrone (http://en.wikipedia.org/wiki/Minestrone) :D

>>> BTW, I wonder what would happen when calling your proposed std::swap for
>>> a type that has a non-public swap member function... Would it try to
>>> call the member function (causing a compile error), or would it consider
>>> the type to be non-MemberSwappable?
>> My understanding of concepts is very limited and I could not find an
>> authoritative answer in paper N2501. I hope someone more knowledgeable
>> will answer this question, as I am curious about it too.
>
> I really hope that a class that has a non-public swap member function
> will be considered non-MemberSwappable. Anyway, you should definitely
> try ConceptGCC! :-) Please note that it still has some issue regarding
> access to non-public members: Ticket #22, "Concept maps should not be
> able to access private data",
> http://svn.osl.iu.edu/trac/conceptgcc/ticket/22

I tried ConceptGCC and if the swap() member is private, then the class
silently fails to satisfy the MemberSwappable concept. That's what you
(and me) expected and that's good news! However, I still don't find in
paper N2501 precise wording that clarifies why this is happening...

Cheers,

Ganesh

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Niels Dekker - no return address on
>> I guess one would need to change the implementation of the
>> boost::optional<T>::swap member function, to directly call your
>> std::swap:
>>
>> void swap( optional & arg )
>> {
>> // Calling the new C++0x std::swap by Barbati & Mett:
>> std::swap(*this, arg);
>> }


Alberto Ganesh Barbati wrote:
> Hmmm... however if you do so you would force all users of
> boost::optional to provide a concept_map, because in absence of a
> concept_map, std::swap() would call the swap() member, causing an
> endless loop.

Oops, I forgot to provide a general concept_map for boost::optional<T>!

concept_map std::Swappable<boost::optional<T>>
{
void swap(boost::optional<T>& a, boost::optional<T>& b)
{
// implementation here, taken from the original
// boost::swap(boost::optional<T>& a, boost::optional<T>& b)
}
}


Adding this concept_map would avoid endless recursion, because your std::swap
implementation would check the Swappable concept_map, before trying the
MemberSwappable concept. :-)

> I believe that the member swap() should just perform
> the "default", non-optimal swap.

Hmmm... I believe that doing a.swap(b) should always be equivalent to doing
swap(a,b)! IMO, the member and the non-member swap function should be kept in
sync. So for a template class that allows customizing its non-member swap,
having the member swap call the non-member swap appears The Right Thing To Do.

> The user is expected to always call std::swap(), by doing so she would
> always get the best swap method available.
>
> Member swap() should be an ingredient of the std::swap() recipe, users
> should use the recipe, not the ingredient directly, unless they know
> what they're doing.

Well, at least it's clear that your C++0x std::swap would come with a new set
of user guidelines. As long as the member swap remains a public member
function, it's hard to tell the user not the call it. In "old" C++03 it was
actually even recommended to prefer calling member functions to algorithms
with the same names! Scott Meyers, Effective STL, item 44,
http://www.informit.com/content/images/0201749629/items/item44-2.pdf
Moreover, in C++03, the swap member function is the only one that provides
swapping a temporary.


> I tried ConceptGCC and if the swap() member is private, then the class
> silently fails to satisfy the MemberSwappable concept. That's what you
> (and me) expected and that's good news!

Cool :-)

So, are you going to write another proposal?

Kind regards, Niels


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Alberto Ganesh Barbati on
Niels Dekker - no return address ha scritto:
>
> Hmmm... I believe that doing a.swap(b) should always be equivalent to doing
> swap(a,b)! IMO, the member and the non-member swap function should be kept in
> sync. So for a template class that allows customizing its non-member swap,
> having the member swap call the non-member swap appears The Right Thing To Do.

I don't know about swap(a,b), all I care is std::swap(a,b) ;) According
to my proposal if the type is MemberSwappable then std::swap(a,b) is
equivalent to a.swap(b) *except* when an explicit Swappable concept_map
is provided. It might not be unconceivable to provide a different
proposal where MemberSwappable takes precedence over a Swappable concept
map, but do we really want that?

>> The user is expected to always call std::swap(), by doing so she would
>> always get the best swap method available.
>>
>> Member swap() should be an ingredient of the std::swap() recipe, users
>> should use the recipe, not the ingredient directly, unless they know
>> what they're doing.
>
> Well, at least it's clear that your C++0x std::swap would come with a new set
> of user guidelines. As long as the member swap remains a public member
> function, it's hard to tell the user not the call it. In "old" C++03 it was
> actually even recommended to prefer calling member functions to algorithms
> with the same names! Scott Meyers, Effective STL, item 44,
> http://www.informit.com/content/images/0201749629/items/item44-2.pdf

Yes, I know that. But that recommendations were about specific types or
templates (containers in particular) and not about truly generic
programming. For "known" types, it is conceivable that no explicit
Swappable concept_map exists: in that case the choice among the two is
equivalent. In generic code, however, std::swap might be preferable, at
least because you don't know in advance whether a swap member is available.

> Moreover, in C++03, the swap member function is the only one that provides
> swapping a temporary.

That would no longer be an issue in C++0X :)

>> I tried ConceptGCC and if the swap() member is private, then the class
>> silently fails to satisfy the MemberSwappable concept. That's what you
>> (and me) expected and that's good news!
>
> Cool :-)
>
> So, are you going to write another proposal?
>

I would like to, but maybe I should get some more feedback about a few
controversial points before doing it.

Thanks!

Ganesh

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]