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

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • petschy

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

    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<Zx = y. X<Zx(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<in t>&)'

    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<intd3 = d, since D<intd2(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<typena me T>
    class C
    {
    public:
    C() { }
    C(const C&) { }
    };

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


    int main()
    {
    A a;
    B b;
    C<intc;
    D<intd;

    A a2(a);
    B b2(b);
    C<intc2(c);
    D<intd2(d);
    C<intc3 = c;
    D<intd3 = d; // <--- compiler error

    return 0;
    }

  • Micah Cowan

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

    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<Zx = y. X<Zx(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<in t>&)'
    >
    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<intd3 = d, since D<intd2(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<typena me T>
    class C
    {
    public:
    C() { }
    C(const C&) { }
    };
    >
    template<typena me T>
    class D
    {
    public:
    explicit D() { }
    explicit D(const D&) { }
    };
    >
    >
    int main()
    {
    A a;
    B b;
    C<intc;
    D<intd;
    >
    A a2(a);
    B b2(b);
    C<intc2(c);
    D<intd2(d);
    C<intc3 = c;
    D<intd3 = d; // <--- compiler error
    >
    return 0;
    }

    Comment

    Working...