mardi 29 août 2017

C++: Rules of Implicit and templated constructors

If I have the following code

template <bool X> struct B {
    B() {}
    B(const B<false> &b) {}
};

template <bool X> struct A {
    A() {}
    A(const A<false> &a) {}
    A(const B<X> &b) {}
};

B<false> b;
A<true> a(b);

that does not compile, saying the call a(b) is ambiguous, and rightfully so. It could call either

  1. implicit A(const B<X> &b) and explicit A(const A<false> &a)
  2. implicit B(const B<false> &b) and explicit A(const B<X> &b)

However, if I have this

template <bool X, typename Y> struct B {
    B() {}
    B(const B<false, Y> &b) {}
};

template <bool X> struct A {
    A() {}
    A(const A<false> &a) {}
    template <typename Y>
    A(const B<X, Y> &b) {}
};

B<false, void> b;
A<true> a(b);

it no longer gives an error. Am I to assume that A(const B<X, Y> &b) is no longer a valid converting constructor because it is templated? And therefore the only possible path is #2?

Of what any other rules should I be aware, regarding converting constructors and templates?

Thanks

Aucun commentaire:

Enregistrer un commentaire