Solution: Type-Based Addition and Type Information
Learn to obtain the type information of objects using standard type traits, and solve the type-based addition challenge.
We'll cover the following...
Type-based addition using standard type traits
Let’s execute the provided solution for the type-based addition challenge and observe the code output. Subsequently, we’ll dissect the code step by step.
Press + to interact
#include <iostream>#include <type_traits>#include <string>template<typename T>constexpr bool always_false = std::false_type::value;template<typename T>struct is_string : std::false_type {};template<>struct is_string<std::string> : std::true_type {};template<typename, typename... Ts>struct has_common_type : std::false_type {};template<typename... Ts>struct has_common_type<std::void_t<std::common_type_t<Ts...>>, Ts...> : std::true_type {};template<typename... Ts>constexpr bool has_common_type_v = sizeof...(Ts) < 2 || has_common_type<void, Ts...>::value;// Template function to identify type for a single variabletemplate<typename T>std::string get_type_info(T t) {if constexpr (std::is_integral_v<T>)return "Type: integral";else if constexpr (std::is_floating_point_v<T>)return "Type: floating-point";else if constexpr (std::is_pointer_v<T>)return "Type: pointer";else if constexpr (is_string<T>::value)return "Type: string";elsereturn "Type: others";}// Template function to perform type-based addition of different variablestemplate<typename T, typename U>decltype(auto) type_based_addition(T a, U b) {if constexpr (has_common_type_v<T, U> && std::is_arithmetic_v<U>)return a + b;else if constexpr (std::is_convertible_v<T, std::string> && std::is_convertible_v<U, std::string>)return std::string(a) + std::string(b);else if constexpr (std::is_convertible_v<T, std::string> && std::is_arithmetic_v<U>)return std::string(a) + std::to_string(b);else if constexpr (std::is_arithmetic_v<T> && std::is_convertible_v<U, std::string>)return std::to_string(a) + std::string(b);elsestatic_assert(always_false<T>, "Invalid combination of types");}// Function template to print type information for multiple variablestemplate<typename A, typename B>void add(A a, B b) {std::cout << get_type_info(a) << ", value: " << a << ", "<< get_type_info(b) << ", value: " << b << ", "<< "Output: " << type_based_addition(a, b) << std::endl;}int main() {std::string hello("Hello ");std::string world("world!");int a = 100, b = 1, year = 2023;float x = 3.5;const char* char_ptr = "Metaprogramming ";// Code for calling these functionsadd(a, b); // Output: 101add(b, x); // Output: 4.5add(hello, world); // Output: Hello world!add(char_ptr, year); // Output: Metaprogramming 2023return 0;}
Explanation
Let’s go over how each code block works in the widget above.
Lines 1–3: Import input/output, type trait, and string header files to the code.
Lines 5–6: Define the template variable
always_false<T>
that is always set tofalse
....