The program test tag dispatching pattern, where the function process_data(tag, a, b) can accept 2 tags int_tag, float_tag. There are 3 case:
int_taganda, bareint-> printa + bfloat_taganda,barefloat-> printa * b- print
unsupportedfor every other case
The correct implementation is inside comment block. I'm trying to implement it another way, but current code always output unsupported isntead of calling the correct int/float version of process_data.
Why is the current implementation wrong? Compiled with -std=c++20
#include <iostream>
#include <type_traits>
#include <vector>
#include <string>
// ------------------------------------------------------------
// Tag types: int_tag and float_tag
// ------------------------------------------------------------
struct int_tag {};
struct float_tag {};
// ------------------------------------------------------------
// 2) Primary template: process_data (generic version)
// ------------------------------------------------------------
// template <typename Tag, typename T, typename U>
// void process_data(Tag tag, const T& a, const U& b) {
// std::cout << "<unsupported type>" << "\n";
// }
template <typename Tag, typename A, typename B, typename Enable = void>
void process_data(Tag tag, const A& a, const B& b) {
std::cout << "<unsupported type>" << "\n";
}
// ------------------------------------------------------------
// 3) Tag-dispatched function for int_tag (sum two integral numbers)
// ------------------------------------------------------------
// template <typename T, typename U>
// std::enable_if_t<std::is_integral_v<T> && std::is_integral_v<U>, void>
// process_data(int_tag, const T& a, const U& b) {
// std::cout << "Result: " << (a + b) << "\n"; // Sum for integral types
// }
template <typename A, typename B, std::enable_if_t<std::is_integral_v<A> && std::is_integral_v<B>>>
void process_data(int_tag, const A& a, const B& b) {
std::cout << "Result: " << (a + b) << "\n";
}
// ------------------------------------------------------------
// 4) Tag-dispatched function for float_tag (multiply two floating-point numbers)
// ------------------------------------------------------------
// template <typename T, typename U>
// std::enable_if_t<std::is_floating_point_v<T> && std::is_floating_point_v<U>, void>
// process_data(float_tag, const T& a, const U& b) {
// std::cout << "Result: " << (a * b) << "\n"; // Product for floating-point types
// }
template <typename A, typename B, std::enable_if_t<std::is_floating_point_v<A> && std::is_floating_point_v<B>>>
void process_data(float_tag, const A& a, const B& b) {
std::cout << "Result: " << (a * b) << "\n";
}
// ------------------------------------------------------------
// TESTS (do NOT change)
// ------------------------------------------------------------
int main() {
bool all_ok = true;
// Test: process_data for int_tag
std::cout << "[process_data for int_tag]\n";
std::cout << "int: ";
process_data(int_tag{}, 10, 20); // Should print: Result: 30
std::cout << "float: ";
process_data(float_tag{}, 3.14f, 2.0f); // Should print: Result: 6.28
std::cout << "string: ";
process_data(int_tag{}, "Hello", "World"); // Should print: <unsupported type>
return 0;
}
AandBare both integral thenstd::enable_if_t<std::is_integral_v<A> && std::is_integral_v<B>>yields a non-type template parameter with incomplete typevoidmaking template impossible to instantiate. That's not how SFINAE supposed to work. see en.cppreference.com/w/cpp/language/sfinae.html