// Copyright (C) 2023 johannst
enum Kind {
kPrimary,
kTT,
kIntBool,
kIntInt,
};
// (1) Primary template.
template<typename T, typename U = bool>
struct pair {
static constexpr Kind kind = kPrimary;
};
// (2) Partial template specialization.
template<typename T>
struct pair<T, T> {
static constexpr Kind kind = kTT;
};
// (3) Template specialization.
template<>
struct pair<int, bool> {
static constexpr Kind kind = kIntBool;
};
// (4) Template specialization.
template<>
struct pair<int, int> {
static constexpr Kind kind = kIntInt;
};
int main() {
static_assert(pair<int>::kind == kIntBool, "");
// * Compare template arg list with primary template, we only supplied one
// arg, the second one will be defaulted as
// pair<int, bool>
// * Compare template arg list against available specializations, this will
// try to match the pattern <int, bool> against the patterns defined in the
// partial specializations.
// * (2) <int, bool> pattern does not match
// * (3) <int, bool> pattern does match
// * (4) <int, bool> pattern does not match
// * Pick the most specialized version -> (3)
static_assert(pair<char, char>::kind == kTT, "");
// * Compare template arg list against available specializations, this will
// try to match the pattern <char, char> against the patterns defined in the
// partial specializations.
// * (2) <char, char> pattern does match
// * (3) <char, char> pattern does not match
// * (4) <char, char> pattern does not match
// * Pick the most specialized version -> (2)
static_assert(pair<int, int>::kind == kIntInt, "");
// * Compare template arg list against available specializations, this will
// try to match the pattern <int, int> against the patterns defined in the
// partial specializations.
// * (2) <int, int> pattern does match
// * (3) <int, int> pattern does match
// * (4) <int, int> pattern does not match
// * Pick the most specialized version -> (3)
static_assert(pair<char, short>::kind == kPrimary, "");
// * Compare template arg list against available specializations, this will
// try to match the pattern <char, short> against the patterns defined in the
// partial specializations.
// * (2) <char, short> pattern does not match
// * (3) <char, short> pattern does not match
// * (4) <char, short> pattern does not match
// * No specialization matches, take the primary template.
}