When applying SFINAE to a template with multiple parameters, you can introduce additional unused template parameters for each one that needs to be constrained.
For example, let's say we have a ProcessPair
template that takes two type parameters T
and U
, and we want to ensure that T
and U
both have a process()
member function:
#include <type_traits>
#include <iostream>
struct SomeType {
int Value;
void process() {
std::cout << "Processing " << Value << '\n';
}
};
using std::enable_if_t, std::is_same_v,
std::declval;
template<typename T, typename U,
enable_if_t<is_same_v<decltype(
declval<T>().process()), void>, int> = 0,
enable_if_t<is_same_v<decltype(
declval<U>().process()), void>, int> = 0
>
void ProcessPair(T a, U b) {
a.process();
b.process();
std::cout << "Processed pair of objects";
}
int main() {
ProcessPair(SomeType{1}, SomeType{2});
}
Processing 1
Processing 2
Processed pair of objects
Here we've added two unused template parameters, one for each of T
and U
. Each one uses std::enable_if
with a condition that checks if the type has a process()
member function returning void
.
If either T
or U
doesn't satisfy the condition, a substitution failure will occur, removing this template from the overload set.
By chaining multiple unused parameters like this, we can constrain any number of the template's type parameters using SFINAE.
Answers to questions are automatically generated and may not have been reviewed.
Learn how SFINAE allows templates to remove themselves from overload resolution based on their arguments, and apply it in practical examples.