Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > template copy constructor vs normal copy constructor

Reply
Thread Tools

template copy constructor vs normal copy constructor

 
 
cinsk
Guest
Posts: n/a
 
      09-26-2010
hi.

I just read the definition of the std:air in <utility>. std:air
has following two copy constructors:

template <class T1, class T2>
struct pair {

pair:air(const pair &);

template<class U1, class U2> pair:air(const pair<U1, U2> &);
...
};

The definition of both copy constructor looks same in my gentoo Linux/
gcc 4.4.3.

Although I'm not good at template, both copy constructors look same to
me.

Q1. What is the purpose of the second copy constructor?
Could you give me some short example code that actually calls
the second copy constructor?

Q2. What happen if the second copy construct is missing?

Q3. How can the compiler determine which copy constructor is used?
In my poor understanding, it looks like that compile would
complain for the ambiguity.

Q4. If I want to make a template class, do I need to provide both copy
constructor?
If not, which is better? And why?

Thank you.
 
Reply With Quote
 
 
 
 
Kai-Uwe Bux
Guest
Posts: n/a
 
      09-26-2010
cinsk wrote:

> hi.
>
> I just read the definition of the std:air in <utility>. std:air
> has following two copy constructors:
>
> template <class T1, class T2>
> struct pair {
>
> pair:air(const pair &);
>
> template<class U1, class U2> pair:air(const pair<U1, U2> &);
> ...
> };
>
> The definition of both copy constructor looks same in my gentoo Linux/
> gcc 4.4.3.
>
> Although I'm not good at template, both copy constructors look same to
> me.
>
> Q1. What is the purpose of the second copy constructor?
> Could you give me some short example code that actually calls
> the second copy constructor?


It allows to copy construct a std:air<double,double> from a
std:air<int,int>.

> Q2. What happen if the second copy construct is missing?


The above would not be possible

> Q3. How can the compiler determine which copy constructor is used?
> In my poor understanding, it looks like that compile would
> complain for the ambiguity.


The ambiguity you worry about arises as copy-constructing std:air<int,int>
from std:air<int,int> matches both. That is true. In that case, overload
resolution kicks in. In this case, the ambiguity is resolved in favor of the
non-templated constructor.

> Q4. If I want to make a template class, do I need to provide both copy
> constructor?
> If not, which is better? And why?


Unless you have the situation where you want a Foo<T> to be copy-
constructible from Foo<S>, you should just go with the first.


Best

Kai-Uwe Bux
 
Reply With Quote
 
 
 
 
cinsk
Guest
Posts: n/a
 
      09-26-2010
On Sep 27, 12:30*am, Kai-Uwe Bux <(E-Mail Removed)> wrote:
> cinsk wrote:
> > hi.

>
> > I just read the definition of the std:air in <utility>. *std:air
> > has following two copy constructors:

>
> > template <class T1, class T2>
> > struct pair {

>
> > * pair:air(const pair &);

>
> > * template<class U1, class U2> pair:air(const pair<U1, U2> &);
> > * ...
> > };

>
> > The definition of both copy constructor looks same in my gentoo Linux/
> > gcc 4.4.3.

>
> > Although I'm not good at template, both copy constructors look same to
> > me.

>
> > Q1. What is the purpose of the second copy constructor?
> > * * * Could you give me some short example code that actually calls
> > the second copy constructor?

>
> It allows to copy construct a std:air<double,double> from a
> std:air<int,int>.
>
> > Q2. What happen if the second copy construct is missing?

>
> The above would not be possible
>
> > Q3. How can the compiler determine which copy constructor is used?
> > * * * In my poor understanding, it looks like that compile would
> > complain for the ambiguity.

>
> The ambiguity you worry about arises as copy-constructing std:air<int,int>
> from std:air<int,int> matches both. That is true. In that case, overload
> resolution kicks in. In this case, the ambiguity is resolved in favor of the
> non-templated constructor.
>
> > Q4. If I want to make a template class, do I need to provide both copy
> > constructor?
> > * * * If not, which is better? And why?

>
> Unless you have the situation where you want a Foo<T> to be copy-
> constructible from Foo<S>, you should just go with the first.
>
> Best
>
> Kai-Uwe Bux


Thank you for the kind answers!

Regards,
 
Reply With Quote
 
Juha Nieminen
Guest
Posts: n/a
 
      09-26-2010
Kai-Uwe Bux <(E-Mail Removed)> wrote:
>> pair:air(const pair &);
>>
>> template<class U1, class U2> pair:air(const pair<U1, U2> &);

>
> It allows to copy construct a std:air<double,double> from a
> std:air<int,int>.


Of course this could raise the question of why that *first* copy
constructor is necessary at all, then (because wouldn't the second
one cover also the case where the types are the same)?

IIRC there was some kind of special rule about constructors and
templates in play here. Could someone refresh my memory?
 
Reply With Quote
 
Bo Persson
Guest
Posts: n/a
 
      09-26-2010
Juha Nieminen wrote:
> Kai-Uwe Bux <(E-Mail Removed)> wrote:
>>> pair:air(const pair &);
>>>
>>> template<class U1, class U2> pair:air(const pair<U1, U2> &);

>>
>> It allows to copy construct a std:air<double,double> from a
>> std:air<int,int>.

>
> Of course this could raise the question of why that *first* copy
> constructor is necessary at all, then (because wouldn't the second
> one cover also the case where the types are the same)?
>
> IIRC there was some kind of special rule about constructors and
> templates in play here. Could someone refresh my memory?


Yes, the first constructor is a copy constructor, the second one is a
converting constructor.

12.8 says that a template is never a copy constructor.


Bo Persson


 
Reply With Quote
 
Juha Nieminen
Guest
Posts: n/a
 
      09-26-2010
Bo Persson <(E-Mail Removed)> wrote:
> 12.8 says that a template is never a copy constructor.


What is the rationale for that rule?
 
Reply With Quote
 
Armen Tsirunyan
Guest
Posts: n/a
 
      09-26-2010
On Sep 27, 12:24*am, Juha Nieminen <(E-Mail Removed)> wrote:
> Bo Persson <(E-Mail Removed)> wrote:
> > 12.8 says that a template is never a copy constructor.

>
> * What is the rationale for that rule?


I am not an expert, but I'll give it a try. Maybe because the copy
constructor is ALWAYS declared, and the declaration is not a template
one?
 
Reply With Quote
 
Johannes Schaub (litb)
Guest
Posts: n/a
 
      09-27-2010
Juha Nieminen wrote:

> Bo Persson <(E-Mail Removed)> wrote:
>> §12.8 says that a template is never a copy constructor.

>
> What is the rationale for that rule?


In C++03, there appears to be no way to declare a copy constructor even if
that rule were absent. This is because you need the first parameter to be
based on the current class type. But if it includes template parameters of
itself, this can never be the case:

struct A {
template<typename T>
A(... /* where to put T!? */);
};

In C++0x this is possible by just using default arguments

struct A {
template<typename T = int>
A(A const&);
};

So the actual reason might be that a template is not really a function. It's
a template that first need to be instantiated.

There is another rule that a template cannot be used to instantiate a copy
constructor. But that rule's history is quite amusing. I have seen people in
here argue about it and its desired meaning, but it appears it's very
simple: http://www.open-std.org/jtc1/sc22/wg...tive.html#1080 .
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      09-27-2010
On Sep 27, 3:00 pm, "Johannes Schaub (litb)" <(E-Mail Removed)>
wrote:
> Juha Nieminen wrote:
> > Bo Persson <(E-Mail Removed)> wrote:
> >> 12.8 says that a template is never a copy constructor.


> > What is the rationale for that rule?


> In C++03, there appears to be no way to declare a copy
> constructor even if that rule were absent. This is because you
> need the first parameter to be based on the current class
> type. But if it includes template parameters of itself, this
> can never be the case:


> struct A {
> template<typename T>
> A(... /* where to put T!? */);
> };


> In C++0x this is possible by just using default arguments


> struct A {
> template<typename T = int>
> A(A const&);
> };


> So the actual reason might be that a template is not really
> a function. It's a template that first need to be
> instantiated.


> There is another rule that a template cannot be used to
> instantiate a copy constructor. But that rule's history is
> quite amusing. I have seen people in here argue about it and
> its desired meaning, but it appears it's very
> simple:http://www.open-std.org/jtc1/sc22/wg...tive.html#1080.


It's not that simple, because when copying an object, normal
overload resolution is done. The "copy constructor" has no
priviledged role. What is important is that a template function
cannot ever be a copy constructor, which means that it won't
prevent the compiler from generating one, e.g.:

struct A
{
template<typename T>
A(T const& other) { std::cout << "Copying" << std::endl; }
};

int
main()
{
A a;
A b(a);
return 0;
}

will output nothing (since the compiler generated copy
constructor is an equally good match as the template, and when
two functions are otherwise equally good matches, the
non-template wins). Drop the const in the signature of the
constructor template, and the template will win, since it is
a better match. (The compiler generated copy constructor will
still be generated, and be used when copying a temporary.)

Of course, if the compiler generated copy constructor doesn't do
what you want, you'll have to define one in addition to the
templated one, or you'll spend a lot of time tracking down
obscure errors.

--
James Kanze

 
Reply With Quote
 
Johannes Schaub (litb)
Guest
Posts: n/a
 
      09-27-2010
James Kanze wrote:

> On Sep 27, 3:00 pm, "Johannes Schaub (litb)" <(E-Mail Removed)>
> wrote:
>> Juha Nieminen wrote:
>> > Bo Persson <(E-Mail Removed)> wrote:
>> >> §12.8 says that a template is never a copy constructor.

>
>> > What is the rationale for that rule?

>
>> In C++03, there appears to be no way to declare a copy
>> constructor even if that rule were absent. This is because you
>> need the first parameter to be based on the current class
>> type. But if it includes template parameters of itself, this
>> can never be the case:

>
>> struct A {
>> template<typename T>
>> A(... /* where to put T!? */);
>> };

>
>> In C++0x this is possible by just using default arguments

>
>> struct A {
>> template<typename T = int>
>> A(A const&);
>> };

>
>> So the actual reason might be that a template is not really
>> a function. It's a template that first need to be
>> instantiated.

>
>> There is another rule that a template cannot be used to
>> instantiate a copy constructor. But that rule's history is
>> quite amusing. I have seen people in here argue about it and
>> its desired meaning, but it appears it's very
>> simple:http://www.open-std.org/jtc1/sc22/wg...tive.html#1080.

>
> It's not that simple, because when copying an object, normal
> overload resolution is done. The "copy constructor" has no
> priviledged role. What is important is that a template function
> cannot ever be a copy constructor, which means that it won't
> prevent the compiler from generating one, e.g.:
>


That's clear anyway because only a non-template constructor can be a copy
constructor. What I meant is that people disagreed on what that statement
means to never instantiate a constructor to do the copy

- Templates are just ignored when doing overload resolution when copying a
class object of type A to another object of type A
- Templates are considered, but if an instantiation is needed the program
either needs to explicitly instantiate the constructor or explicitly
specialize it to provide a suitable specialization.
- Templates are considered, but overload resolution ignores any candidates
for which argument deduction yields a parameter list with "cv T" as type.

The issue was further confused by a footnote that explicitly allowed a
template constructor to be used to copy the object in C++03, and that note
was removed from the C++0x draft. And now they get to it again and see they
shouldn't had removed that footnote.


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
how to call an inherited, template class constructor from initializerlist of an inheriting, non-template class constructor l.s.rockfan@web.de C++ 4 11-15-2008 01:22 PM
how to call an inherited, template class constructor from initializerlist of an inheriting, non-template class constructor l.s.rockfan@web.de C++ 2 11-14-2008 10:04 PM
A constructor calling another constructor (default constructor)? Generic Usenet Account C++ 10 11-28-2007 04:12 AM
Calling base class constructor from derived class Copy constructor ali C++ 4 03-05-2007 09:15 AM
Copy constructor hides default constructor Aire C++ 3 01-25-2004 05:47 PM



Advertisments