Reputation: 357
Why the output is 0003212 ?
#include <iostream>
using namespace std;
template<typename X> class C
{
public:
C() { cout<<"0";}
template<class T> C(const C<T>& c) { cout<<"1";}
C(const C<int>& c) { cout<<"2";}
template<class T> C(const C<T*>& c) { cout<<"3";}
};
int main(int argc, char* args[])
{
C<int> c1; // 0
C<double> c2; // 0
C<int*> c3; // 0
C<int> c4(c3); // 3
C<int> c5(c1); // 2
C<int> c6(c2); // 1
C<float> c7(c1); // 2
C<double> c8(c2); // ?
std::cin.get();
return 0;
}
What is invoked in the last meaning line?
I can suppose that it's some auto-created ctor but can't figure out which one.
Upvotes: 3
Views: 187
Reputation: 283634
There are several C++ language rules in play here.
A template cannot be a copy constructor. (Standard rule 12.8p2)
A non-template constructor for class
X
is a copy constructor if its first parameter is of typeX&
, constX&
,volatile X&
orconst volatile X&
, and either there are no other parameters or else all other parameters have default arguments.
If no copy constructor is defined, the compiler generates a default one (if possible). (Standard rule 12.8p7)
If the class definition does not explicitly declare a copy constructor, one is declared implicitly. If the class definition declares a move constructor or move assignment operator, the implicitly declared copy constructor is defined as deleted; otherwise, it is defined as defaulted (8.4). The latter case is deprecated if the class has a user-declared copy assignment operator or a user-declared destructor. Thus, for the class definition
struct X { X(const X&, int); };
a copy constructor is implicitly-declared. If the user-declared constructor is later defined as
X::X(const X& x, int i =0) { /∗ ... ∗/ }
then any use ofX
's copy constructor is ill-formed because of the ambiguity; no diagnostic is required.
If a template and non-template are an equally good match for the arguments, the non-template wins. (Standard rule 13.3.3) The rule is a big hard-to-digest mess, I'll show just the important part:
[...] a viable function
F1
is defined to be a better function than another viable functionF2
if [...rules about argument matching...] or, if not that,F1
is a non-template function andF2
is a function template specialization [...]
From the code you provided, only
C<int>::C(const C<int>&)
is a user-defined copy-constructor that prints 2
. All X
other than int
don't define a copy-constructor, so the compiler creates one.
See also
Upvotes: 5
Reputation: 2031
It's copy constructor generated for you by compiler, and since it's best match it's selected in last case.
Upvotes: 4