Reputation: 1534
I would like to understand how the standard determines which partial specialization to pick below. For example, does it have anything to do with number of template parameters in the specialization? Otherwise, how does it determine the "best-fit" match?
#include <cstdint>
template <int ...I>
struct Vector;
template <typename T>
struct Transform;
template <int x, int ...I>
struct Transform<Vector<x,x,I...>> {
using type = int;
};
template <int ...I>
struct Transform<Vector<I...>> {
using type = char;
};
int main() {
static_assert(sizeof(Transform<Vector<1,1,2>>::type) == 4);
}
Upvotes: 3
Views: 72
Reputation: 4713
No, it works differently. It has some dominance functionality. If a specialization is clearly further specializes another then it is chosen but otherwise it is ambiguous. The method isn't too intelligent and is meant to deal with simple cases. In any complicated case you'd better make sure there is no ambiguity at all.
For instance, neither
template <int x, int y, int ...I>
struct Transform<Vector<x, y, y, y, I...>> {
using type = short;
};
nor
template <int x, int y, int ...I>
struct Transform<Vector<x, y, y, x, I...>> {
using type = short;
};
is a further specialization of the two x
case
template <int x, int ...I>
struct Transform<Vector<x, x, I...>> {
using type = int;
};
So if you were to declare either one then Transform<Vector<1,1,1,1>>
would be ambiguous. To resolve it you'd have to define the specialization for Vector<x, x, x, x, I...>
or restrict the previous ones.
However, if instead of the above you were to define
template <int x, int y, int ...I>
struct Transform<Vector<x, x, y, y, I...>> {
using type = short;
};
Then it would be the chosen form for Transform<Vector<1,1,1,1>>
- as this clearly further specializes the two x
case.
Upvotes: 1