Section: 16.4.4.2 [utility.arg.requirements] Status: CD1 Submitter: Howard Hinnant Opened: 2007-05-04 Last modified: 2016-01-28
Priority: Not Prioritized
View all other issues in [utility.arg.requirements].
View all issues with CD1 status.
Discussion:
The current Swappable
is:
Table 37: Swappable
requirements [swappable]expression return type post-condition swap(s,t)
void
t
has the value originally held byu
, andu
has the value originally held byt
The Swappable requirement is met by satisfying one or more of the following conditions:
T
is Swappable ifT
satisfies theCopyConstructible
requirements (Table 34) and theCopyAssignable
requirements (Table 36);T
is Swappable if a namespace scope function namedswap
exists in the same namespace as the definition ofT
, such that the expressionswap(t,u)
is valid and has the semantics described in this table.
With the passage of rvalue reference into the language, Swappable
needs to be updated to
require only MoveConstructible
and MoveAssignable
. This is a minimum.
Additionally we may want to support proxy references such that the following code is acceptable:
namespace Mine { template <class T> struct proxy {...}; template <class T> struct proxied_iterator { typedef T value_type; typedef proxy<T> reference; reference operator*() const; ... }; struct A { // heavy type, has an optimized swap, maybe isn't even copyable or movable, just swappable void swap(A&); ... }; void swap(A&, A&); void swap(proxy<A>, A&); void swap(A&, proxy<A>); void swap(proxy<A>, proxy<A>); } // Mine ... Mine::proxied_iterator<Mine::A> i(...) Mine::A a; swap(*i1, a);
I.e. here is a call to swap
which the user enables swapping between a proxy to a class and the class
itself. We do not need to anything in terms of implementation except not block their way with overly
constrained concepts. That is, the Swappable
concept should be expanded to allow swapping
between two different types for the case that one is binding to a user-defined swap
.
Proposed resolution:
Change 16.4.4.2 [utility.arg.requirements]:
-1- The template definitions in the C++ Standard Library refer to various named requirements whose details are set out in tables 31-38. In these tables,
T
is a type to be supplied by a C++ program instantiating a template;a
,b
, andc
are values of typeconst T
;s
andt
are modifiable lvalues of typeT
;u
is a value of type (possiblyconst
)T
; andrv
is a non-const
rvalue of typeT
.
Table 37: Swappable
requirements [swappable]expression return type post-condition swap(s,t)
void
t
has the value originally held byu
, andu
has the value originally held byt
The
Swappable
requirement is met by satisfying one or more of the following conditions:
T
isSwappable
ifT
satisfies theMoveConstructible requirements (TableCopyConstructible
3433) and theMoveAssignable requirements (TableCopyAssignable
3635);T
isSwappable
if a namespace scope function namedswap
exists in the same namespace as the definition ofT
, such that the expressionswap(t,u)
is valid and has the semantics described in this table.
[
Kona (2007): We like the change to the Swappable
requirements to use
move semantics. The issue relating to the support of proxies is
separable from the one relating to move semantics, and it's bigger than
just swap. We'd like to address only the move semantics changes under
this issue, and open a separated issue (742) to handle proxies. Also, there
may be a third issue, in that the current definition of Swappable
does
not permit rvalues to be operands to a swap operation, and Howard's
proposed resolution would allow the right-most operand to be an rvalue,
but it would not allow the left-most operand to be an rvalue (some swap
functions in the library have been overloaded to permit left operands to
swap to be rvalues).
]