4

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>)?

SergeyA
  • 61,605
  • 5
  • 78
  • 137
  • Non-type parameters is problematic as I remember, Doing some test with class specialization has issue with similar comparison [Demo](https://godbolt.org/z/vv659j9sT) even if the class way work in that case... :/ – Jarod42 Sep 17 '21 at 15:01
  • Overloading and templates is a hairy combination. The "partial ordering process" part of [this page](https://en.cppreference.com/w/cpp/language/function_template#Function_template_overloading) is relevant, but gives me too much of a headache to want to figure it out. – molbdnilo Sep 17 '21 at 15:01

1 Answers1

-2

"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

JDługosz
  • 5,592
  • 3
  • 24
  • 45
  • 1
    Function template specializations can be more specialized: https://timsong-cpp.github.io/cppwp/over#match.best.general-2.5 – NathanOliver Sep 17 '21 at 14:36
  • @NathanOliver I clarified – JDługosz Sep 17 '21 at 14:37
  • 1
    My question is why call to qwe is success and call to asd is fail because of ambiguous . if it is second function has fewer template arguments don't make it better match,why `void qwe(TypeFlag,TypeFlag)` is a better match but `void asd(SizeFlag , SizeFlag)` don't. PS. it is https://en.cppreference.com/w/cpp/language/function_template#Function_template_overloading use "more specialized" in "Function template overloading" to describe better match. – uncertainty principle Sep 17 '21 at 15:37
  • @uncertaintyprinciple because that's what the rules state! `T*` is a more specialized template match. Arbitrarily picking a template with fewer template arguments is not anything special. Go through the rules listed at that reference page and see why the example works; go through the non-working example and reach the end without it determining a preference. – JDługosz Sep 20 '21 at 13:59