 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Stephan Tolksdorf Guest
|
Posted: Fri Jul 21, 2006 3:27 am Post subject: Template conversion and default copy constructor |
|
|
Hi
All the compilers I tested produced from the following code executables
that printed "2". Shouldn't the implicitly defined copy constructor be
called?
--
#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;
}
--
Regards,
Stephan
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Earl Purple Guest
|
Posted: Fri Jul 21, 2006 7:40 pm Post subject: Re: Template conversion and default copy constructor |
|
|
Stephan Tolksdorf wrote:
| Quote: | Hi
All the compilers I tested produced from the following code executables
that printed "2". Shouldn't the implicitly defined copy constructor be
called?
--
#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;
}
--
|
No, the default copy-constructor is a closer match (being an exact
match) than the templated one and is called instead.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Frederick Gotham Guest
|
Posted: Fri Jul 21, 2006 7:42 pm Post subject: Re: Template conversion and default copy constructor |
|
|
Stephan Tolksdorf posted:
| Quote: | Shouldn't the implicitly defined copy constructor be
called?
|
Nice catch.
Indeed, vanilla functions take precedence over template functions.
Does the Standard say that template functions can replace the "miranda"
member functions? I don't think it clarifies that point.
--
Frederick Gotham
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Victor Bazarov Guest
|
Posted: Fri Jul 21, 2006 7:44 pm Post subject: Re: Template conversion and default copy constructor |
|
|
Stephan Tolksdorf wrote:
| Quote: | All the compilers I tested produced from the following code
executables that printed "2". Shouldn't the implicitly defined copy
constructor be called?
--
#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;
}
|
No. A templated constructor never replaces the [compiler-defined]
copy constructor.
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Matthias Hofmann Guest
|
Posted: Sat Jul 22, 2006 8:20 am Post subject: Re: Template conversion and default copy constructor |
|
|
"Stephan Tolksdorf" <andorxor (AT) gmx (DOT) de> schrieb im Newsbeitrag
news:e9omrk$3ku$1 (AT) news01 (DOT) versatel.de...
| Quote: | Hi
All the compilers I tested produced from the following code executables
that printed "2". Shouldn't the implicitly defined copy constructor be
called?
|
<Skipping code>
You are right, the output should be "3", which is the case with Microsoft
Visual C++ 7.0. Which compilers have you tested?
--
Matthias Hofmann
Anvil-Soft, CEO
http://www.anvil-soft.com - The Creators of Toilet Tycoon
http://www.anvil-soft.de - Die Macher des Klomanagers
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
kanze Guest
|
Posted: Sat Jul 22, 2006 8:24 am Post subject: Re: Template conversion and default copy constructor |
|
|
Stephan Tolksdorf wrote:
| Quote: | All the compilers I tested produced from the following code
executables that printed "2". Shouldn't the implicitly defined
copy constructor be called?
--
#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;
}
|
That's a good question. I don't see any context where the copy
constructor is implicitly called for. In "Test t2(t1);" (or for
that matter, in "Test t2 = t1;", since t1 and t2 have the same
type), the standard says simply that "The applicable
constructors are enumerated, and the best one is chosen through
oeverload resolution." The implicit copy constructor is there,
of course, and is considered in overload resolution, so it is a
question of which is the better match. (If they are otherwise
equal, preference goes to the non-template version.) In this
case, I think that binding the non-const object to a non-const
reference wins out, by the rule in §13.3.3.2/2, point 5: "S1 and
S2 are reference bindings, and the types to which the reference
refers are the same type except for top-level cv-qualifiers, and
the type to which the reference initialized by S2 refers is more
cv-qualifed than the type to which the reference initialized by
S1 refers." (There is, presumably, an "S1 is a better
conversion sequence than S2" somewhere before the list of
points, but I can't find it.) Basically, this is the same rule
which makes the compiler prefer non-const functions to const, or
in general a non-const reference to a const reference, when the
call would be legal for both.
If you change the parameter of the template constructor to T
const&, the compiler generated default should be called.
Similarly, if you explicitly provide a copy constructor which
takes a non-const Test&, it should be provided. But in the case
at hand, t1 is considered a better match for T& (where T is
instantiated as Test) than for the Test const& parameter of the
implicitly generated constructor.
--
James Kanze GABI Software
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! ] |
|
| Back to top |
|
 |
Gene Bushuyev Guest
|
Posted: Sat Jul 22, 2006 11:12 pm Post subject: Re: Template conversion and default copy constructor |
|
|
"Stephan Tolksdorf" <andorxor (AT) gmx (DOT) de> wrote in message
news:e9omrk$3ku$1 (AT) news01 (DOT) versatel.de...
| Quote: | Hi
All the compilers I tested produced from the following code executables
that printed "2". Shouldn't the implicitly defined copy constructor be
called?
--
#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;
}
--
|
You are absolutely right, the implicitly generated copy constructor should be
called. So all the compilers you tested that print 2 have bugs. I also got "2"
from gcc 3.3.1 and vc8, but amazingly Borland bcc32 5.82 got it right printing
"3"
Good catch.
--
Gene Bushuyev (www.gbresearch.com)
----------------------------------------------------------------
To see what is in front of one's nose needs a constant struggle ~ George Orwell
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Matthias Hofmann Guest
|
Posted: Sat Jul 22, 2006 11:12 pm Post subject: Re: Template conversion and default copy constructor |
|
|
| Quote: | Nice catch.
Indeed, vanilla functions take precedence over template functions.
Does the Standard say that template functions can replace the "miranda"
member functions? I don't think it clarifies that point.
|
At least for the case of copy constructors, it does:
12.8/3: "A member function template is never instantiated to perform the
copy of a class object to an object of its class type."
--
Matthias Hofmann
Anvil-Soft, CEO
http://www.anvil-soft.com - The Creators of Toilet Tycoon
http://www.anvil-soft.de - Die Macher des Klomanagers
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Matthias Hofmann Guest
|
Posted: Sat Jul 22, 2006 11:13 pm Post subject: Re: Template conversion and default copy constructor |
|
|
| Quote: | No, the default copy-constructor is a closer match (being an exact
match) than the templated one and is called instead.
|
The reason that the implicitly defined copy constructor must be called is
the following:
12.8/3: "A member function template is never instantiated to perform the
copy of a class object to an object of its class type."
Matthias Hofmann
Anvil-Soft, CEO
http://www.anvil-soft.com - The Creators of Toilet Tycoon
http://www.anvil-soft.de - Die Macher des Klomanagers
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Stephan Tolksdorf Guest
|
Posted: Sat Jul 22, 2006 11:14 pm Post subject: Re: Template conversion and default copy constructor |
|
|
Earl Purple wrote:
| Quote: | Stephan Tolksdorf wrote:
Hi
All the compilers I tested produced from the following code executables
that printed "2". Shouldn't the implicitly defined copy constructor be
called?
--
#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;
}
--
No, the default copy-constructor is a closer match (being an exact
match) than the templated one and is called instead.
|
That was my initial thought too, but is it really an exact match? The
implicitly-declared copy constructor uses a *const* reference.
If there were two copy constructors, one taking a const reference and
one taking a non-const reference, Test(t1) would be resolved to a call
to the non-const reference constructor. Footnote 106) in 12.8.2 of the
standard says: "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 the other constructors."
So, isn't the template constructor the better match and hence should be
called?
Stephan
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Seungbeom Kim Guest
|
Posted: Sat Jul 22, 2006 11:17 pm Post subject: Re: Template conversion and default copy constructor |
|
|
Earl Purple wrote:
| Quote: | Stephan Tolksdorf wrote:
Hi
All the compilers I tested produced from the following code executables
that printed "2". Shouldn't the implicitly defined copy constructor be
called?
--
#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;
}
--
No, the default copy-constructor is a closer match (being an exact
match) than the templated one and is called instead.
|
Then why does t2.data get 2, which must be from the template constructor?
If the default copy constructor were called, it should get 3.
And this is precisely the point that the OP seems to have made,
but strangely people are saying "No" and then repeating the OP's point..
What am I missing here?
--
Seungbeom Kim
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Kai-Uwe Bux Guest
|
Posted: Sat Jul 22, 2006 11:28 pm Post subject: Re: Template conversion and default copy constructor |
|
|
Jiang wrote:
| Quote: |
Earl Purple wrote:
Stephan Tolksdorf wrote:
Hi
All the compilers I tested produced from the following code
executables that printed "2". Shouldn't the implicitly defined copy
constructor be called?
--
#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;
}
--
No, the default copy-constructor is a closer match (being an exact
match) than the templated one and is called instead.
Not true.
In 12.8.p3, the standard says that a member function template
is never instantiated to perform the copy of a class object to an
object of its class type.
So overload resolution is totally irrelative here in my mind.
|
12.8/3 refers to constructors with signature
X ( X )
not to copy constructors, whose signature must be
X ( X [const] [volatile] & )
Thus, 12.8/3 does not apply here.
Best
Kai-Uwe Bux
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
James Kanze Guest
|
Posted: Sat Jul 22, 2006 11:31 pm Post subject: Re: Template conversion and default copy constructor |
|
|
Victor Bazarov wrote:
| Quote: | Stephan Tolksdorf wrote:
All the compilers I tested produced from the following code
executables that printed "2". Shouldn't the implicitly defined copy
constructor be called?
--
#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;
}
No. A templated constructor never replaces the [compiler-defined]
copy constructor.
|
I'm not sure what you mean by "replaces" here. A templated constructor
never inhibits the generation of the compiler default. But it is still
considered in overload resolution, in cases where the copy constructor
is not required. In the above code, there is no place where the
standard specifies that the copy constructor should be used. In all of
the constructors in this code, overload resolution is used to decide
which constructor to call. And since the instantiated template function
is a better match than the default copy constructor, it gets called.
--
James Kanze kanze.james (AT) neuf (DOT) 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! ] |
|
| Back to top |
|
 |
James Kanze Guest
|
Posted: Sat Jul 22, 2006 11:31 pm Post subject: Re: Template conversion and default copy constructor |
|
|
Frederick Gotham wrote:
| Quote: | Stephan Tolksdorf posted:
Shouldn't the implicitly defined copy constructor be
called?
Nice catch.
Indeed, vanilla functions take precedence over template functions.
|
They did, if I recall correctly, in some early implementations.
According to the standard, however, non-template over template is only a
tie-breaker, used in cases where the two functions were otherwise equal.
| Quote: | Does the Standard say that template functions can replace the
"miranda" member functions? I don't think it clarifies that point.
|
A templated constructor never inhibates the generation of the default
copy constructor, and a templated constructor is never used as a copy
constructor. Since there were no cases where the standard called for a
copy constructor in the original code, however, this is irrelevant.
Function overload resolution occurs, and the constructor
Test::Test(Test&) (instantiation of the template) is a better match than
Test::Test(Test const&) (the compiler generated default copy
constructor).
--
James Kanze kanze.james (AT) neuf (DOT) 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! ] |
|
| Back to top |
|
 |
James Kanze Guest
|
Posted: Sun Jul 23, 2006 12:31 am Post subject: Re: Template conversion and default copy constructor |
|
|
Earl Purple wrote:
| Quote: | Stephan Tolksdorf wrote:
All the compilers I tested produced from the following code executables
that printed "2". Shouldn't the implicitly defined copy constructor be
called?
--
#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;
}
--
No, the default copy-constructor is a closer match (being an exact
match) than the templated one and is called instead.
|
I think you mistyped here. Didn't you mean the reverse? (The basic way
the sentence is formulated suggests to me that you actually did
understand what was going on, and just inversed the two terms when
typing.)
--
James Kanze kanze.james (AT) neuf (DOT) 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! ] |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|