Non-type template function overloading problem

168 Views Asked by At

Consider:

template <size_t >
class SizeFlag {};

template <size_t START, size_t END>
void asd(SizeFlag<START>, SizeFlag<END>) {
}

template <size_t START>
void asd(SizeFlag <START>, SizeFlag<START + 1>) {
}

template <class T>
class TypeFlag{};

template <class T,class F>
void qwe(TypeFlag<T>,TypeFlag<F>){}

template <class T>
void qwe(TypeFlag<T>,TypeFlag<T*>){}

int main()
{
    asd(SizeFlag<1>{}, SizeFlag<2>{});// call to 'asd' is ambiguous in clang-11
    qwe(TypeFlag<int>{}, TypeFlag<int*>{});// use void qwe(TypeFlag<T>,TypeFlag<T*>) 
    cout << "Hello CMake." << endl;
    return 0;
}

Why is qwe(TypeFlag<T>,TypeFlag<T*>) more specialized than qwe(TypeFlag<T>,TypeFlag<F>), but void asd(SizeFlag <START>, SizeFlag<START + 1>) is not more specialized than void asd(SizeFlag<START>, SizeFlag<END>)?

1

There are 1 best solutions below

4
On

"more specialized" applies to your class templates, not the functions as you wrote them. The functions are overloaded, and not "related" in the same way that the partial specialization of classes is.

You did not write something like

template <size_t START>
void asd<>(something something) {
}

That is, there's no <> in your second function. It is simply overloaded, not a specialization of the same template.

The rules to determining if a function argument is a better match are things like T vs T&, and don't consider that the second function has fewer template arguments than the first.

The complete rules can be seen at https://en.cppreference.com/w/cpp/language/function_template#Function_template_overloading