473,394 Members | 1,737 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

Template and Copy constructor

Just a little sample :

class A
{
public:
A( )
{
}
template<typename T> A( const typename T& a)
{
}
};

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.

A a; // This called the default constructor
A b( a ); // This called the default Copy constructor and not mine !!!
A c( 3 ); // This called my template constructor
A d( 3.0f ); // This called my template constructor
return 0;
}

Why the default copy constructor is called instead of mine when I'm using template constructor ? This compile fine but the default constructor is not the good one used when creating A b( a ); Is there something wrong there ?
Thanks for help !
Nov 17 '05 #1
13 2896
MurphyII wrote:
Just a little sample :

class A
{
public:
A( )
{
}
template<typename T> A( const typename T& a)
{
}
};

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.

A a; // This called the default constructor
A b( a ); // This called the default Copy constructor and not
mine !!! A c( 3 ); // This called my template constructor
A d( 3.0f ); // This called my template constructor
return 0;
}

Why the default copy constructor is called instead of mine when I'm
using template constructor ? This compile fine but the default
constructor is not the good one used when creating A b( a ); Is there
something wrong there ? Thanks for help !


There is nothing wrong, rather this is in accordance with the C++ Standard.
A templated constructor will never be considered a copy constructor even if
it's a perfect match on argument types. You need to supply your own copy
constructor if the compiled-supplied one is inadequate for your class.

-cd
Nov 17 '05 #2
But there is no warning... It's not really the behaviour we are expecting and I think nobody knows it... Ok, thanks for your help !
Nov 17 '05 #3
MurphyII wrote:
But there is no warning... It's not really the behaviour we are
expecting and I think nobody knows it... Ok, thanks for your help !


It's a pretty common trap - comes up on the newsgroups all the time.

An analogous case applies to the copy-assignment operator as well.

FYI: C++ Standard, section 12.8, footnote 106 says

"Because a template constructor is never a copy constructor, the presence of
such a template does not suppress the implicit declaration of a copy
constructor. Template constructors participate in overload resolution with
other constructors, including copy constructors, and a template constructor
may be used to copy an object if it provides a better match than other
constructors."

-cd
Nov 17 '05 #4
MurphyII <an*******@discussions.microsoft.com> wrote:
Just a little sample :

class A
{
public:
A( )
{
}
template<typename T> A( const typename T& a)
{
}
};
I see that Carl has already answered your
question. But I want to point out that
the second 'typename' is not necessary. In
fact, I believe the compiler shouldn't even
accept it. However, VC is very lax with
bogus (or missing) 'typenames'.
[...]

Schobi

--
Sp******@gmx.de is never read
I'm Schobi at suespammers dot org

"Sometimes compilers are so much more reasonable than people."
Scott Meyers

Nov 17 '05 #5
Hendrik Schober wrote:
I see that Carl has already answered your
question. But I want to point out that
the second 'typename' is not necessary. In
fact, I believe the compiler shouldn't even
accept it. However, VC is very lax with
bogus (or missing) 'typenames'.


We might just be ahead of the curve. :-)

In 7.1, we shouldn't be lax about mixxing typenames. The standards committee
is investigating expansion of where typename can go, which actually solves
some common real world problems -- so we may end up implementing it sooner.

--
Brandon Bray, Visual C++ Compiler http://blogs.msdn.com/branbray/
This posting is provided AS IS with no warranties, and confers no rights.
Nov 17 '05 #6
Brandon Bray [MSFT] <br******@online.microsoft.com> wrote:
Hendrik Schober wrote:
I see that Carl has already answered your
question. But I want to point out that
the second 'typename' is not necessary. In
fact, I believe the compiler shouldn't even
accept it. However, VC is very lax with
bogus (or missing) 'typenames'.


We might just be ahead of the curve. :-)

In 7.1, we shouldn't be lax about mixxing typenames. The standards committee
is investigating expansion of where typename can go, which actually solves
some common real world problems -- so we may end up implementing it sooner.

:o>
However, AFAIK, this won't be C++ before
2008. Until then, your compiler remains
broken in this regard.
And, VC7.1 is lax about missing 'typename's,
too, although not as bad as the other way.

Schobi

--
Sp******@gmx.de is never read
I'm Schobi at suespammers dot org

"Sometimes compilers are so much more reasonable than people."
Scott Meyers
Nov 17 '05 #7
Brandon Bray [MSFT] <br******@online.microsoft.com> wrote:
Hendrik Schober wrote:
I see that Carl has already answered your
question. But I want to point out that
the second 'typename' is not necessary. In
fact, I believe the compiler shouldn't even
accept it. However, VC is very lax with
bogus (or missing) 'typenames'.


We might just be ahead of the curve. :-)

In 7.1, we shouldn't be lax about mixxing typenames. The standards committee
is investigating expansion of where typename can go, which actually solves
some common real world problems -- so we may end up implementing it sooner.

:o>
However, AFAIK, this won't be C++ before
2008. Until then, your compiler remains
broken in this regard.
And, VC7.1 is lax about missing 'typename's,
too, although not as bad as the other way.

Schobi

--
Sp******@gmx.de is never read
I'm Schobi at suespammers dot org

"Sometimes compilers are so much more reasonable than people."
Scott Meyers
Nov 17 '05 #8
Hendrik Schober wrote:
However, AFAIK, this won't be C++ before
2008. Until then, your compiler remains
broken in this regard.
Broken isn't quite the right word. This is an extension, and perfectly
allowed in a compiler that has extensions.
And, VC7.1 is lax about missing 'typename's,
too, although not as bad as the other way.


Can you provide examples? Looking through the bug database, there isn't
anything like this. (Well, there is one thing -- typename cannot be used in
a default argument to a function, but that's so uncommon that it has never
been reported by a customer or seen in any real world code.)

--
Brandon Bray, Visual C++ Compiler http://blogs.msdn.com/branbray/
This posting is provided AS IS with no warranties, and confers no rights.
Nov 17 '05 #9
Brandon Bray [MSFT] <br******@online.microsoft.com> wrote:
Hendrik Schober wrote:
However, AFAIK, this won't be C++ before
2008. Until then, your compiler remains
broken in this regard.


Broken isn't quite the right word. This is an extension, and perfectly
allowed in a compiler that has extensions.


Uh, how can I turn this extension off?
And, VC7.1 is lax about missing 'typename's,
too, although not as bad as the other way.


Can you provide examples? Looking through the bug database, there isn't
anything like this. (Well, there is one thing -- typename cannot be used in
a default argument to a function, but that's so uncommon that it has never
been reported by a customer or seen in any real world code.)

I don't have a repro. I know that while
porting to Linux (GCC) and Mac (CW)
superflous 'typename's turn up rather
regularly. Sometimes missing ones, too.
But usually nobody takes the time to
boil down the code to a repro.
If I happen to come across something
and find the time to make one I will
post it here.

Schobi

--
Sp******@gmx.de is never read
I'm Schobi at suespammers dot org

"Sometimes compilers are so much more reasonable than people."
Scott Meyers
Nov 17 '05 #10
Hendrik Schober wrote:
Uh, how can I turn this extension off?


That's not a requirement for compiling non-extension code, so there isn't a
way. Since you seem to be highly concerned about portability, simply
sticking to standards conformance doesn't get you that. Highly portable
programs can make use of very little of what is in the standard.

We do spend a lot of time working towards compiling standards conforming
programs. Working towards limitting programs to standards conformance
doesn't really benefit our customers. First, there is really no test suite
to judge this, which means if we were to expend energy on it, you would be
required to trust our implementation. Secondly, it's actually a poor
barometer of what you actually want -- portability.

All that said, we do have plans on making sure programmers know when they're
using highly visible extensions. In this case, this is a pesky issue that
spending any time on our part wouldn't really help you out. The compilers
you use on other platforms may not be correct either. To get the result you
want, you must use the intersection of the features. That, in practice, has
nothing to do with the standard (other than we know generally the
intersection is supporting more of the standard, but still it is desperately
small).

--
Brandon Bray, Visual C++ Compiler http://blogs.msdn.com/branbray/
This posting is provided AS IS with no warranties, and confers no rights.
Nov 17 '05 #11
Brandon Bray [MSFT] <br******@online.microsoft.com> wrote:
Hendrik Schober wrote:
Uh, how can I turn this extension off?
That's not a requirement for compiling non-extension code, so there isn't a
way. Since you seem to be highly concerned about portability, simply
sticking to standards conformance doesn't get you that. Highly portable
programs can make use of very little of what is in the standard.


Usable highly portable programs can be written
so that at least 80% of the code is C++ only
without any extensions.
And on the platforms we need, VC, CW, GCC, and
Comeau _are_ close enough to the standard so
that we can use just about everything that is
in the standard except 'export'. What remains
are those many little annoyances: This compiler
choking on one little template, that compiler
ICEing on another one, the third one missing
support for two-phase lookup or accepting code
that all the others won't accept because it
is non-standard.
(BTW, usually, VC7.1 is a mix of the second and
the third. <g> )
We do spend a lot of time working towards compiling standards conforming
programs. Working towards limitting programs to standards conformance
doesn't really benefit our customers.
I can understand that most of your customers
won't appreciate you working on disallowing
non-conforming code. However, "most" is not
"all".
First, there is really no test suite
to judge this, which means if we were to expend energy on it, you would be
required to trust our implementation.
The reason for wanting std conforming code
to compile only is that we need to port. And
when you port among a variety of compilers,
code that is non-std usually is found very
quick.
(And you have to admint that como in fact
is pretty close to beeing a good test bed.
So far, I have heard of one bug in it [a GC
bug]. I have yet to find one.)
Secondly, it's actually a poor
barometer of what you actually want -- portability.
That is plain wrong. If you have good, std
conforming compilers (that don't let you
get away with non-std code), sticking to
strictly std conforming code in the plat-
form-indepened 80% of the code takes you a
long way. Since we do have such compilers
on all the needed platforms and since we
follow this route, porting has become a
lot easier.
All that said, we do have plans on making sure programmers know when they're
using highly visible extensions. In this case, this is a pesky issue that
spending any time on our part wouldn't really help you out.
I don't know what you draw this conclusion
from. I think it is wrong.
I think it can be safley assumed that most
of the compiler/library vendors aim for std
conformance. So the more compilers conform,
the more portable is my code. In fact, there
is even more than that: Since the C++ std is
the only general agreement on what C++ really
is, it is the the safest bet I can make when
I need my code to be compilable by more than
one compiler.
The compilers
you use on other platforms may not be correct either.
I did say we use Comeau? <g>
To get the result you
want, you must use the intersection of the features. That, in practice, has
nothing to do with the standard (other than we know generally the
intersection is supporting more of the standard, but still it is desperately
small).


This is wrong. It might be desperately small
when you need some platforms where you depend
on one compiler supplier. However, on the
platforms we target (mainly Win, MacOS, Linux),
it is good. (In fact, for many many years,
your compiler was the cause of most of our
woes. I am really glad that 7.1 has stopped
this.)

Schobi

--
Sp******@gmx.de is never read
I'm Schobi at suespammers dot org

"Sometimes compilers are so much more reasonable than people."
Scott Meyers
Nov 17 '05 #12
When it comes down to every case that you disagree with me, it is a matter
of how many platforms you consider important. Not everyone has exactly the
same matrix of targets that you do. I do have data to back up my claims,
which unfortunately I am not at liberty to disclose it here.

I do completely understand your position. While it is an important customer
scenario, given the totality of the customers using Visual C++, it is by far
not a common scenario. It would be a disservice to our customers at large if
we were to focus on scenarios that bear no benefits to a larger audience.

That said, as you've already pointed out, compiling the same code with
several compilers is already a good way to diagnose portability issues.
Anything we do (or done in other compilers) would be no match to simply
trying to compile the code with several toolsets.

--
Brandon Bray, Visual C++ Compiler http://blogs.msdn.com/branbray/
This posting is provided AS IS with no warranties, and confers no rights.
Nov 17 '05 #13
Brandon Bray [MSFT] <br******@online.microsoft.com> wrote:
When it comes down to every case that you disagree with me, it is a matter
of how many platforms you consider important. Not everyone has exactly the
same matrix of targets that you do. I do have data to back up my claims,
which unfortunately I am not at liberty to disclose it here.
I do not doubt that there are many shops
out there doing different things than what
we do on many different platforms.
I do completely understand your position. While it is an important customer
scenario, given the totality of the customers using Visual C++, it is by far
not a common scenario. It would be a disservice to our customers at large if
we were to focus on scenarios that bear no benefits to a larger audience.
I think I said that I understand that.
Nevertheless, just I have to make sure
that what is important for me ends up
in your data, even though that doesn't
make it as important to you. :o>
That said, as you've already pointed out, compiling the same code with
several compilers is already a good way to diagnose portability issues.
Anything we do (or done in other compilers) would be no match to simply
trying to compile the code with several toolsets.

Of course. However, when you actually do
port to different platforms, you start to
realize what is wrong with the platform
you started with. In other words: While
it is nice that this catches bugs which
the compiler the code was developed on
doesn't catch, it is also very annoying
to have to remove (and sometimes add) all
these 'typename's again and again just
because the compiler the code originally
was developed on doesn't do it "right".

Schobi

--
Sp******@gmx.de is never read
I'm Schobi at suespammers dot org

"Sometimes compilers are so much more reasonable than people."
Scott Meyers
Nov 17 '05 #14

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: jack | last post by:
Hi there, I have a function F(x, y, z) and I want to calculate f(a) + f(b), where f(x) = F(x, x, z0) z0 is fixed. Suppose somebody wrote a routine called "Compute" which simply computes f(a)...
2
by: Indrawati Yahya | last post by:
Hi I am having trouble in defining a templated class' copy constructor. Here is the simplest code that represent my problem: template<typename T1> class Foo { public: Foo(T1 bar = T1()):...
6
by: Gonçalo Rodrigues | last post by:
Hi all, The following (test) program is not working as I expected. Note: The code is a bit long but is easy to understand: There is a class Object implementing ref counting. A Ref<T> template...
3
by: yomgui | last post by:
Hi, The following code compiles on Unix but refuse to do so with devstudio6 can anyone help me to get it right ? (ie for visual studio) template <class T> class AutoPtr { public:
14
by: Bart Samwel | last post by:
Hi everybody, I would really like some help explaining this apparent discrepancy, because I really don't get it. Here is the snippet: void foo(int&); void foo(int const&); ...
3
by: Martin Vorbrodt | last post by:
In "C++ Templates, The Complete Guide" i read that template copy-con is never default copy constructor, and template assignment-op is never a copy assignment operator. Could someone please explain...
9
by: muzmail | last post by:
I have declared a copy constructor for a template class in a Visual C++ project but for some reason the compiler ignores it. I can put syntax errors in the copy constructor and the compiler ignores...
4
by: Deep | last post by:
Can I use a class in this manner, where a constructor is of templated: template<typename T> class my_class{ public: int x_; public: template<typename U> my_class(const my_class<U>& other ) :...
3
by: Fred Kleinschmidt | last post by:
I have a template:: template <class Vclass Vct { public: Vct(V); }; template <class V> Vct<V>::Vct( V vin ) { /*...*/
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.