Specialize member function of class template using C++20 concepts

Viewed 322

I want to specialize a member function of a class template as follows:

#include <concepts>

template <typename T>
struct S {
    void f();
};

template <typename T>
void S<T>::f() {
}

// (0) This is fine.
template <>
void S<int>::f() {
}

// (1) This triggers an error.
template <std::integral T>
void S<T>::f() {
}

The specialization (0) is fine, but specializes f() only for the int type. Instead, I would like to specialize it, e.g., for any integral type, as in (1). Is this possible using C++20 concepts? Notice that std::integral is just an example and that my specific case makes use of user-defined concepts.

1 Answers

Simply use a trailing requires-clause. The compiler will choose the most constrained function:

#include <concepts>
#include <iostream>

template <typename T>
struct S {
    void f();
    
    void f() requires std::integral<T>;
};

template <typename T>
void S<T>::f() {
  std::cout << "general\n";
}

template <typename T>
void S<T>::f() requires std::integral<T> {
  std::cout << "constrained\n";
};


int main() {
  S<int> x;
  S<double> y;
  
  x.f(); // prints constrained
  y.f(); // prints general

  return 0;
}
Related