Tag dispatching is another technique in C++ for selecting function overloads based on properties of types. While it can often be used to solve similar problems as SFINAE, it works in a different way.
With tag dispatching, you define "tag" types that represent certain properties, and then you overload functions based on these tag types. The selection of the overload happens at the point where you determine which tag to pass to the function.
Here's an example that demonstrates tag dispatching:
#include <iostream>
#include <type_traits>
struct integral_tag {};
struct floating_point_tag {};
template <typename T>
constexpr auto get_tag() {
if constexpr (std::is_integral_v<T>)
return integral_tag{};
else
return floating_point_tag{};
}
void foo(integral_tag) {
std::cout << "foo called with"
" an integral type\n";
}
void foo(floating_point_tag) {
std::cout << "foo called with a"
" floating point type\n";
}
template <typename T>
void bar(T value) {
foo(get_tag<T>());
}
int main() {
bar(42); // Calls foo(integral_tag)
bar(3.14); // Calls foo(floating_point_tag)
}
foo called with an integral type
foo called with a floating point type
Here, integral_tag
and floating_point_tag
are empty types that serve as "tags". The get_tag
function returns an integral_tag
if its type argument T
is an integral type, and a floating_point_tag
 otherwise.
We then have two overloads of foo
, one accepting an integral_tag
and the other accepting a floating_point_tag
.
In the bar
function template, we call foo
with the result of get_tag<T>()
. So the selection of which foo
overload to call happens at this point, based on the properties of T
.
The key differences between tag dispatching and SFINAEÂ are:
Both techniques have their uses and can often be used to solve similar problems. Tag dispatching can be more readable in some cases, especially when the conditions for choosing an implementation are complex. However, SFINAE is more flexible and can be used in situations where tag dispatching would be cumbersome or impossible, such as enabling or disabling member functions of class templates.
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.