Using SFINAE to Control Overload Resolution

Interaction between SFINAE and Default Template Arguments

How does SFINAE work with default template arguments?

Illustration representing computer hardware

SFINAE can be used in conjunction with default template arguments to provide different default behaviors based on the properties of the template arguments. Consider this example:

#include <iostream>
#include <string>
#include <type_traits>

using std::enable_if_t, std::is_integral_v;

template <typename T, typename enable_if_t<
  is_integral_v<T>, int>* = nullptr>
void print(T value, int base = 10) {
  std::cout << "Integral value: "
    << std::to_string(value)
    << " (base " << base << ")\n";
}

template <typename T, typename enable_if_t<
  !is_integral_v<T>, int>* = nullptr>
void print(T value, int precision = 2) {
  std::cout << "Non-integral value: "
    << std::to_string(value)
    << " (precision " << precision << ")\n";
}

int main() {
  // Uses first template, base defaults to 10
  print(42);
  // Uses first template, base is 2
  print(42, 2);

  // Uses second template, precision defaults to 2
  print(3.14);
  // Uses second template, precision is 4
  print(3.14, 4);
}
Integral value: 42 (base 10)
Integral value: 42 (base 2)
Non-integral value: 3.140000 (precision 2)
Non-integral value: 3.140000 (precision 4)

Here, we have two print function templates. The first one is enabled if T is an integral type, and it has a default argument base for the output base. The second one is enabled if T is not an integral type, and it has a default argument precision for the output precision.

When we call print(42), the first template is selected because int is an integral type. The base parameter defaults to 10. When we call print(42, 2), the first template is still selected, but we override the default base with 2.

Similarly, when we call print(3.14), the second template is selected because double is not an integral type. The precision parameter defaults to 2. When we call print(3.14, 4), the second template is still selected, but we override the default precision with 4.

This demonstrates how SFINAE can be used to provide different default behaviors for a function based on the properties of its template arguments. This can lead to more intuitive and user-friendly interfaces, as the appropriate defaults are selected automatically based on the types being used.

This Question is from the Lesson:

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.

Answers to questions are automatically generated and may not have been reviewed.

This Question is from the Lesson:

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.

A computer programmer
Part of the course:

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Free, unlimited access

This course includes:

  • 124 Lessons
  • 550+ Code Samples
  • 96% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved