c++template-meta-programmingc++-templates

Template function specialization controlled by enable_if


Suppose I have a template is_my_tag<T> that resolves into true_type or false_type, depending on T.

struct my_tag;
template<class Tags> struct is_my_tag : std::false_type {};
template<> struct is_my_tag<my_tag> : std::true_type {};
template<class... Tags> struct is_my_tag<std::tuple<my_tag, Tags...>> : std::true_type {};

There exists some template function in the library:

template<class T>
std::string fun(const T& ctx) {
    return "base";
}

I want to specialize it for the types for which is_my_tag<T> == true_type. I tried this code, but it fails to compile, reporting "ambiguous definition":

template<class T, typename = std::enable_if_t<is_my_tag<T>::value>>
std::string fun(const T& ctx) {
    return "override";
}

What is the correct way to write override, assuming that I have no access to the base definition?

If it matters, I use g++13


Solution

  • With C++20 subsumption, you might add overload with constraint:

    template<class T>
    requires is_my_tag<T>::value
    std::string fun(const T&) {
        return "override";
    }
    

    Demo

    For previous version, without changing original, you might add better overload (which mostly duplicate is_my_tag definition)

    std::string fun(const my_tag&) {
        return "override";
    }
    template<class... Tags>
    std::string fun(const std::tuple<my_tag, Tags...>&) {
        return "override";
    }
    

    Demo