Search code examples
c++templatesc++20c++-concepts

Specialise Member Function If Type Satisifies Concept


Consider a struct which has a member function which needs to have a different implementation for types which satisfy some concept. I attempted to implemented the struct as follows:

template<typename T>
concept CanDouble = requires (T a) {
    a + a;
};

template<typename T>
struct Foo {
    T Load() {
        return m_bar;
    }

    T m_bar;
};

template<typename T> requires CanDouble<T>
T Foo<T>::Load() {
    return m_bar + m_bar;
}

However, this does not compile (type constraint differs in template redeclaration). What is the correct way to implement this functionality?

This earlier question (Full specialisation of a class template using a C++20 concept of a non-type template parameter) seems to want something similar, however that specialises the entire class (not just the member function).


Solution

  • You can specialize the member function with if constexpr

    T Load() {
      if constexpr (CanDouble<T>)
        return m_bar + m_bar;
      else
        return m_bar;
    }
    

    Or provide a constrained overload that is instantiated when the concept is satisfied

    T Load() {
      return m_bar;
    }
    
    T Load() requires CanDouble<T> {
      return m_bar + m_bar;
    }