#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;
}
#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;
}