Applying SFINAE to Non-Type Template Parameters

Can I use SFINAE with non-type template parameters, like integers?

Yes, SFINAE can be applied to non-type template parameters as well, such as integers, enums, or pointers.

For example, let's say we want to write a ToString function that converts an integral value to a string, but we only want to enable it for unsigned integral types. We can achieve this using SFINAE on a non-type template parameter:

#include <type_traits>
#include <string>

using std::enable_if_t, std::is_unsigned_v;
template<typename T,
  enable_if_t<is_unsigned_v<T>, int> = 0
>
std::string ToString(T value) {
  return std::to_string(value);
}

Here, the second template parameter is an unused non-type parameter of type int. The std::enable_if condition checks if T is an unsigned type using the std::is_unsigned type trait.

If T is unsigned, the second parameter will have a type of int and the template will be viable. If T is not unsigned, a substitution failure occurs, removing this template from the overload set.

We can test it like this:

#include <type_traits>
#include <string>

using std::enable_if_t, std::is_unsigned_v;
template<typename T,
  enable_if_t<is_unsigned_v<T>, int> = 0
>
std::string ToString(T value) {
  return std::to_string(value);
}

int main() {
  unsigned int x = 42;
  int y = -10;

  // OK
  std::string sx = ToString(x);

  // Substitution failure, int is not unsigned
  std::string sy = ToString(y);
}

So SFINAE works consistently with both type and non-type template parameters. The key is to introduce an unused parameter whose validity depends on the properties you want to constrain.

Using SFINAE to Control Overload Resolution

Learn how SFINAE allows templates to remove themselves from overload resolution based on their arguments, and apply it in practical examples.

Questions & Answers

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

Using SFINAE with Multiple Template Parameters
How can I apply SFINAE when my template has multiple parameters?
Interaction between SFINAE and Overloaded Functions
How does SFINAE interact with normal overloaded functions?
SFINAE vs Concepts: Which should I use?
I've heard that C++20 Concepts can replace SFINAE. Should I still learn SFINAE?
Using SFINAE to Check for Member Types
Can I use SFINAE to check if a type has a specific member type?
Interaction between SFINAE and Default Template Arguments
How does SFINAE work with default template arguments?
Applying SFINAE to Variadic Templates
Can SFINAE be used with variadic templates?
Tag Dispatching vs SFINAE
What is tag dispatching and how does it differ from SFINAE?
Or Ask your Own Question
Get an immediate answer to your specific question using our AI assistant