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

Discussion in 'C++' started by petschy, Dec 15, 2006.

  1. petschy

    petschy Guest

    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;
    }
     
    petschy, Dec 15, 2006
    #1
    1. Advertising

  2. petschy

    Micah Cowan Guest

    petschy wrote:
    > 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.

    >
    > 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;
    > }
     
    Micah Cowan, Dec 15, 2006
    #2
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Apricot
    Replies:
    4
    Views:
    560
    velthuijsen
    Apr 16, 2004
  2. Mr. SweatyFinger
    Replies:
    2
    Views:
    2,226
    Smokey Grindel
    Dec 2, 2006
  3. NVH
    Replies:
    8
    Views:
    520
    mlimber
    Jul 6, 2006
  4. , India

    copy ctor vs default ctor

    , India, Aug 15, 2007, in forum: C++
    Replies:
    2
    Views:
    432
    =?ISO-8859-1?Q?Erik_Wikstr=F6m?=
    Aug 15, 2007
  5. puzzlecracker
    Replies:
    8
    Views:
    454
    James Kanze
    Apr 15, 2008
Loading...

Share This Page