Interaction between SFINAE and Default Template Arguments
How does SFINAE work with default template arguments?
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.
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.