aboutsummaryrefslogblamecommitdiffhomepage
path: root/development/c++/tmpl-pair.cc
blob: a8acaed77c01e4fb14b936b21d1c08f6f8972d56 (plain) (tree)








































































                                                                                   
// 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.
}