Using SFINAE with member function templates

Can I use SFINAE (Substitution Failure Is Not An Error) with member function templates? How does that work?

Yes, you can use SFINAE with member function templates. SFINAE is a powerful metaprogramming technique that allows you to write template code that can be selectively enabled or disabled based on the template arguments.

Here's a simple example of how you might use SFINAE with a member function template:

#include <iostream>
#include <type_traits>

class MyClass {
 public:
  template <typename T, std::enable_if_t<
    std::is_integral_v<T>, bool> = true>
  void func(T x) {
    std::cout << "func for integral types: "
      << x << std::endl;
  }

  template <typename T, std::enable_if_t<
    std::is_floating_point_v<T>, bool> = true>
  void func(T x) {
    std::cout << "func for floating-point "
      "types: " << x << std::endl;
  }
};

int main() {
  MyClass obj;
  // calls func for integral types
  obj.func(42);    

  // calls func for floating-point types
  obj.func(3.14);
}
func for integral types: 42
func for floating-point types: 3.14

In this code, MyClass has two member function templates named func. Both take a single parameter x of type T. However, they also have a second, unnamed template parameter.

This second parameter uses std::enable_if and type traits to conditionally enable or disable each function. The first func is only enabled if T is an integral type, while the second func is only enabled if T is a floating-point type.

When we call obj.func(42), the compiler tries to instantiate both templates. The first one succeeds because int is an integral type, but the second one fails because int is not a floating-point type. However, because of SFINAE, this failure is not an error. The compiler simply discards the second template and uses the first one.

Similarly, when we call obj.func(3.14), the first template fails (because double is not an integral type), but the second one succeeds.

SFINAE allows you to write templates that adapt to the capabilities of their template arguments. This can be used for things like conditionally providing different implementations based on the presence of certain member functions or operators in the template arguments.

However, SFINAE can also make your code more complex and harder to read, so it should be used judiciously. Modern C++ also provides other mechanisms for conditional templates, like if constexpr and concepts, which can often be simpler and clearer than SFINAE.

Member Function Templates

Learn how to create and use member function templates in classes and structs, including syntax, instantiation, and advanced techniques

Questions & Answers

Answers are generated by AI models and may not have been reviewed. Be mindful when running any code on your device.

When should I use member function templates vs regular member functions?
How do I decide when it makes sense to use a member function template instead of a regular member function?
Passing member function templates as arguments
Can I pass a member function template as an argument to another function? How would I do that?
Template specialization for member function templates
Is it possible to specialize a member function template? How would I do that?
Using member function templates with inheritance
How do member function templates interact with inheritance? Can I override a member function template in a derived class?
Member function templates and static members
Can I declare a static member variable inside a member function template? How would I define it?
Or Ask your Own Question
Get an immediate answer to your specific question using our AI assistant