Re: Template conversion and default copy constructor
Jiang wrote:
All the compilers I tested produced from the following code executables
that printed "2". Shouldn't the implicitly defined copy constructor be
called?
Yes, template constructor is constructor, but it will never be used as
copy constructor, since we need consistent copy semantics in every
TUs.
Correct, but the key to understanding what is occuring here is to
realize that there is no "copying", in the sense of the standard. So
normal function overloading takes place, and the instantiation of the
template is a better match. (But I'll admit that I had to reread the
relevant passages in the standard several times myself before I came to
this conclusion. Overload resolution is all to often a guessing game,
in which you try to guess what the compiler will do this time.)
I tested your example using gcc, cl, como and icl, only icl gives
correct/expected result.
My icl shows me that:
$ cat test.cpp
#include <iostream>
class Test{
public:
Test() : data(0) {}
template <typename T> Test(T& test) : data(2) { }
int data;
};
int main(int argc, char* argv[]) {
Test t1;
t1.data = 3;
Test t2(t1);
std::cout << t2.data;
}
$ icl test.cpp
Intel(R) C++ Compiler for 32-bit applications, Version 9.0 Build
20050430Z
Copyright (C) 1985-2005 Intel Corporation. All rights reserved.
test.cpp
Microsoft (R) Incremental Linker Version 7.10.3077
Copyright (C) Microsoft Corporation. All rights reserved.
-out:test.exe
test.obj
$ ./test
3
Except that the correct answer here is 2.
#BTW, if you change the template constructor as (add const specifier):
// ...
template <typename T> Test(T const & test) : data(2) { }
then all compilers will give you correct answer "3".
One of the subtilities of operator overloading and template type
deduction. Template type deduction generates the constructor
Test::Test(Test&) in the original code, which is a better match than the
default Test::Test(Test const&). With the above modification, it
generates Test::Test(Test const&), which is an equal match with the
compiler generated default (which is always present), and in case of an
otherwise equal match, the non template compiler generated default gets
the nod.
--
James Kanze kanze.james@neuf.fr
Conseils en informatique orient?e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S?mard, 78210 St.-Cyr-l'?cole, France +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]