Pergunta

I'm trying to understand, why GCC chooses f(char, A<C, 5> &var) for overload-resolution in the code below:

template <class C, int N> struct A { };
template <class C> struct A<C, 8> { static_assert(sizeof(C) > 8, "Assertion in A<C,8>"); };
template <class C> struct A<C, 5> { static_assert(sizeof(C) < 8, "Assertion in A<C,5>"); operator A<C,8>&(); };

template <class C> void f(double, A<C,8> &var);
template <class C> void f(char, A<C,5> &var);

int main(void)
{
    A<int, 5> a;
    f(4., a);
}

There are two overloads available:

template <class C> void f(double, A<C,8> &var);

4. exact matches double (no implicit conversion required), but user defined conversion required for second parameter. So this overload: exact match & user-define conversion

Next overload, which is matched by GCC:

template <class C> void f(char, A<C,5> &var);

4. requires implicit conversion to char but exact match for A<C,5>. Is there any reason why GCC choose this overload over previous one?

Can someone find an evidence from section 13 of standard about this particular case? Any help or comment is appreciated. Thank you!

Foi útil?

Solução

Deduction cannot succeed for

template <class C> void f(double, A<C,8> &var);

and an argument of type A<int, 5>. I.e. there's no possible type C that could make A<C,8> match the argument type A<int,5>. That a conversion is possible doesn't care for deduction.

See [temp.deduct.call]/4. As conversions can be allowed through converting constructors as well as conversion functions, it isn't possible to consider (all) conversions for type deduction. It could also lead to ambiguities.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top