JTC1/SC22/WG21
N0718
Document Number: WG21/N0718
X3J16/95-0118
Date: 8 July 1995
Project: Programming Language C++
Reply to: Sean A. Corfield
sean@corf.demon.co.uk
Templates and Special Member Functions
Abstract
We have the facility to explicitly invoke a destructor inside a template
for an arbitrary type (dependent on a template parameter), even if that
type is in fact a builtin type.
This raises the question of what other operations are, or should be,
permitted and what other special member functions should be considered.
This paper proposes that it should be possible to explicitly invoke the
assignment operator and that it should be possible to take the address
of the assignment operator.
Status quo & Rationale
The following is currently well-formed:
template<typename T> void f(T* p) {
p->~T();
}
regardless of the type with which 'f' is instantiated. The following is
also well-formed:
template<typename T> T& g(T& a, const T& b) {
return a = b;
}
for both builtin types and user-defined types (assuming the 'usual'
definition of the assignment operator). However, an explicit invocation
of the assignment operator is not well-formed for all types:
template<typename T> T& g1(T& a, const T& b) {
return a.operator=(b);
}
This seems inconsistent. Furthermore, since the assignment operator is
'just' another member function, it would seem reasonable to be able to
write:
template<typename T> void h(T& a, const T& b) {
T& (T::*pmf)(const T&) = &T::operator=;
(a.*pmf)(b);
}
Proposal 1
In the same way that explicit invocation of the destructor is allowed in
templates for arbitrary types, explicit invocation of the assignment
operator, using the functional form, should be permitted. I believe this
should be non-controversial.
Proposal 2
It should be possible to form a pointer to member for the assignment
operator for arbitrary types. For builtin types, this would require the
generation, by the compiler, of a trivial function that performed the
assignment. I do not believe this would present significant difficulty
for implementors, nor incur any overhead unless the instantiation
required the address.
Note: this assumes that it is currently possible to form the pointer to
member for implicitly generated assignment operators for user-defined
types -- I am not certain that this is the case, but if it is not, I
believe it should be.
This second proposal may in fact be editorial and/or already allowed
by the WP.
WP changes 1
In 12.8 [class.copy] (or perhaps 13.? [over.ass]) add the following
wording:
The notation for explicit call of a copy assignment operator can be
used for any scalar type name. [Note: allowing this makes it
possible to write code without having to know if an explicit
assignment operator exists for a given type. [Example:
int* p;
// ...
p->operator=(0);
--end example] --end note]
WP changes 2
It is not clear (to me, at least) whether this is already permitted
by the wording in the WP.