Re: template copy constructor vs normal copy constructor
On Oct 9, 5:21 pm, "Johannes Schaub (litb)" <schaub-johan...@web.de>
wrote:
Blanchet Florian wrote:
In article <i8pkvg$20r$0...@news.t-online.com>, Johannes Schaub (litb)
says...
It says that a constructor of class X whose first parameter
is of type "cv X&" and either there are no other parameters
or all other parameters have default arguments, is a copy
constructor. This does not apply to the above template, and
so it is *not* a copy constructor.
I'm agree with James. It's not a copy constructor because
the draft says "A non-template constructor for class X is a
copy constructor if ..." and not only "its first parameter
is of type X&,...".
If it was just "its first parameter is of type X&,...", the
result of
struct A { template<class T> A(T&){std::cout << 0} };
int main() { A a; A b(a); return 0; }
would be "0", because the template constructor A<A>(A&) is a
constructor and is first parameter is of type A&. And the
result isn't "0".
I keep disagreeing This is allegedly forbidden (by the
interpretation of some people) by another paragraph, namely
12.8/p3 "A member function template is never instantiated to
perform the copy of a class object to an object of its class
type." (See the other post of me where I link to an issue
report about the interpretation of this).
You're quoting out of context there. Paragraph 12.8/p3 is
talking about constructors taking the class (and not a reference
to the class) as a parameter. It's not very well worded, but I
think what it's trying to say is that:
struct A
{
template<typename T>
A(T) {}
};
will never be instantiated with T == A. (But I need to read the
entire section, as well as paragraph 8.5/14, to understand this,
because it sure isn't what I'd understand reading the paragraph
in isolation. It is, in fact, misleading enough that I think a
DR is in order.)
12.8/p2 has nothing to do with it.
Paragraph 12.8 *is* the definition of a copy constructor.
(Notice that the word copy is in italics.)
The stuff you quote from p2 says that a *non-template* can be
a copy constructor - in other words a template cannot be a
copy constructor. A function instantiated from a template is
not a template. So it does entirely not apply, see below.
Since when does "is" mean "can" in English. The sentence is
quite clear: "A non-template constructor for class X is a copy
constructor if[...]". Not can be, or might be, or anything
else. This is where the standard defines copy constructor.
In addition, nothing says that only copy constructors are
allowed to copy an object.
Nobody is arguing that. Although there is some very strange
text in paragraph 8, which suggests that the following might
hold:
// No const on the template function.
struct A { template<typename T> A(T&) { cout << 0; } };
// Now a class with a copy-ctor which takes a non-const
// reference.
struct B { B(B&); };
// Inheriting from B means that the compiler generated
// copy-ctor will have the signature C(C&), without a
// const.
struct C : A, B {};
int main()
{
A a;
A b(a); // Outputs 0.
C c;
C d(c); // Doesn't output anything.
}
Paragraph 8 says that if the subobject is of class type (the
case here), the copy constructor will be used. Since the
template function clearly is not a copy constructor, and the
class has a copy constructor (provided by the compiler), that
copy constructor will be used, even though the template
constructor is a better match.
I'm not sure that this difference is intentional. Again, it's
possible that a DR is in order.
So even if it were like you are
saying and "A non-template ..." makes also the specialization
non-copy constructors, that wouldn't change anything with
regard to your example above.
What it makes sure is that the following template declaration
does not inhibit the implicit declaration of a copy
constructor
Yes, and since that is the effect (and the only effect) of a
user declared copy constructor, that's the issue.
--
James Kanze