Topic: Contradiction in the Standard. Overload resolution between copy
Author: vlad.moscow@mail.ru
Date: Sun, 11 Mar 2012 00:22:55 -0800 (PST)
Raw View
Early in the C++ Standard there was the phrase ( 12.8.7 ) "7 A member
function template is never instantiated to perform the copy of a class
object to an object of its
class type."
However as it follows from the Standard a template constructor takes
part in overload resolution even for copy initialization.
Let consider an example.
#include <iostream>
struct A
{
template <class T>
A( T & ) { std::cout << "template <class T> A( T & )\n"; }
};
void f1( A a ) {}
void f2( A a )
{
f1( a );
}
void f3( const A &a )
{
f1( a );
}
int main()
{
int i = 10;
A a( i );
f2( a );
f3( a );
return ( 0 );
}
Here the template constructor is called three times. the first time
then object a is created. The second and the third time then it passed
to function f2 and correspondingly to function f1. At least I checked
this with several compilers.
And the implicit copy constructor is called two times then object a is
passed to function f3 and correspondingly to function f1, because the
parameter of f3 declared as const reference.
According to the Standard ( 12.8.1 ) "1 A class object can be copied
or moved in two ways: by initialization (12.1, 8.5), including for
function argument
passing (5.2.2) and for function value return (6.6.3); and by
assignment (5.17). Conceptually, these two operations are implemented
by a copy/move constructor (12.1) and copy/move assignment operator
(13.5.3)."
Take into account what is writtten: that copying is implemented by
copy constructor.
On the other hand there is the folloing phrase in the Standard
( 12.8.2 ): " 2 A non-template constructor for class X is a copy
constructor if its first parameter is of type X&, const X&, volatile
X& or const volatile X&, and either there are no other parameters or
else all other parameters have default arguments (8.3.6). [ Example:
X::X(const X&) and X::X(X&,int=1) are copy constructors."
Again take into account that the copy constructor is a non-template
constructor. However in the example I have shown above the template
consttructor was called for coping initialization.
Let consider another example
#include <iostream>
struct A
{
template <class T>
A( T & ) { std::cout << "template <class T> A( T & )\n"; }
private:
A( const A & ) {}
};
void f1( A a ) {}
void f2( A a )
{
f1( a );
}
int main()
{
int i = 10;
A a( i );
f2( a );
return ( 0 );
}
Here again the template constructor is called though the copy
constructor is explicitly defined as private.
I see here a contradiction and broken semantic of the copy
constructor. It follows that in fact a template constructor is a copy
constructor and role of the copy consttructor totally unclear if we
can do all with a template constructor. So one can say that a copy
consttructor is in fact any constructor template or non-template which
takes a reference to object of the same class as a parameter.
--
[ comp.std.c++ is moderated. To submit articles, try posting with your ]
[ newsreader. If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]