explicit copy ctor in template class : compiler error. why?

P

petschy

hello,

i've run into an error when qualifying a copy ctor 'explicit'. the
strange thing is that i get a compiler error only if the class is a
template and declare the variable as X<Z> x = y. X<Z> x(y) is fine.
Tested with gcc 2.95, 3.3, 4.1, all gave the same error:

t.cpp: In function 'int main()':
t.cpp:44: error: no matching function for call to
'D<int>::D(D<int>&)'

which is quite right, since there is only D(const D&). the thing i
don't understand is why this error only occures if the class is a
template, and if used as D<int> d3 = d, since D<int> d2(d) compiles
fine.

is there a difference between the variable declarations A a(b) and A a
= b? to the best of my knowledge, not, and the compilers seem to
generate the same code for both.

and for the ones asking why i qualify the copy ctor 'explicit' : it's
not needed, but all other ctors were explicit, so i thought, it look
consistent that way, then ran into this issue.

regards, p


here's the code:


class A
{
public:
A() { }
A(const A&) { }
};

class B
{
public:
explicit B() { }
explicit B(const B&) { }
};

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

template<typename T>
class D
{
public:
explicit D() { }
explicit D(const D&) { }
};


int main()
{
A a;
B b;
C<int> c;
D<int> d;

A a2(a);
B b2(b);
C<int> c2(c);
D<int> d2(d);
C<int> c3 = c;
D<int> d3 = d; // <--- compiler error

return 0;
}
 
M

Micah Cowan

petschy said:
hello,

i've run into an error when qualifying a copy ctor 'explicit'. the
strange thing is that i get a compiler error only if the class is a
template and declare the variable as X<Z> x = y. X<Z> x(y) is fine.
Tested with gcc 2.95, 3.3, 4.1, all gave the same error:

t.cpp: In function 'int main()':
t.cpp:44: error: no matching function for call to
'D<int>::D(D<int>&)'

which is quite right, since there is only D(const D&). the thing i
don't understand is why this error only occures if the class is a
template, and if used as D<int> d3 = d, since D<int> d2(d) compiles
fine.

is there a difference between the variable declarations A a(b) and A a
= b? to the best of my knowledge, not, and the compilers seem to
generate the same code for both.

Clearly, you don't know what the keyword "explicit" is supposed to
mean. You are right that there is no difference between those
declarations... /except/ that one involves an explicit use of the copy
constructor and the other an implicit use.

Your problem also has nothing to do with the fact that D<> is a
template. It would've given you the same error had you used B in that
way.
and for the ones asking why i qualify the copy ctor 'explicit' : it's
not needed, but all other ctors were explicit, so i thought, it look
consistent that way, then ran into this issue.

Using "explicit" because that's consistent with how the other
constructors in the same class are declared, is a very poor reason. In
particular, using the "explicit" keyword in constructors that require
more than one argument (or accept no arguments) would be utterly
useless.

You shouldn't use the "explicit" keyword unless you mean it: even if
you have other constructors accept a single argument, and they're all
explicit so far, that doesn't mean you need to make another one
explicit. It should be on a case-by-case basis.

Copy constructors, in particular, should usually not be explicit unless
you have a specific reason to disallow "assignment"-style declarations,
and automatic conversions for (say) function arguments.

For instance, if you had a class you were calling Integer, you would
probably want to make conversions from double explicit, to make sure
the invoker is paying attention to what they're doing, whereas you'd
probably want to leave conversions from plain int implicit.

The std::vector class has a constructor that is capable of taking a
single integer argument (specifying the initial capacity). That one is
declared to be explicit, since a declaration like:

std::vector a = 15;

is not very intuitive at all, and a vector conversion from an integer
function argument would be downright confusing.

A general rule-of-thumb is that, if there is a loss of information in
the conversion (as in the case of double-to-Integer), it should be
explicit. Another good rule is that if an implicit conversion could be
confusing, disallow it.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top