# Specialization ___ ## Function specialization If we want to have the same function name, but we want our code to behave differently for some types, we can create a specialization. ```cpp //generic function template void print(T arg) { std::cout << arg << '\n'; } ``` ```cpp // specialization for `T = double` template <> void print(double arg) { std::cout << std::setprecision(10) << arg << '\n'; } ``` ```cpp // better: overload void print(double arg) { std::cout << std::setprecision(10) << arg << '\n'; } ``` Tip: do not use function specializations. Always prefer function overloads. Template function specializations do not take part in overload resolution. Only the exact type match is considered. Above specialization does not work for `float`. Overload does. ___ ## Class specialization A class can have not only different behaviour (different methods implementations) but also different layouts. You can have completely different fields and/or their values. ___ ## Specialization example #1 - methods ```c++ #include template // primary template struct is_int { bool get() const { return false; } }; template<> // explicit specialization for T = int struct is_int { bool get() const { return true; } }; int main() { is_int iic; is_int iii; std::cout << iic.get() << '\n'; // prints 0 (false) std::cout << iii.get() << '\n'; // prints 1 (true) return 0; } ``` ___ ## Specialization example #2 - field values ```c++ #include template // primary template struct is_int { static constexpr bool value = false; }; template<> // explicit specialization for T = int struct is_int { static constexpr bool value = true; }; int main() { std::cout << is_int::value << '\n'; // prints 0 (false) std::cout << is_int::value << '\n'; // prints 1 (true) return 0; } ``` You can play with the code [here](https://ideone.com/fork/LEIx7e) ___ ## Specialization example #3 - <type_traits> To achieve the last behavior, we can use `std::false_type` and `std::true_type`. The below code is equivalent to the one from the previous example. ```c++ #include using namespace std; template // primary template struct is_int : std::false_type {}; template<> // explicit specialization for T = int struct is_int : std::true_type {}; int main() { std::cout << is_int::value << std::endl; // prints 0 (false) std::cout << is_int::value << std::endl; // prints 1 (true) return 0; } ``` The interactive version of this code is [here](https://ideone.com/fork/GaTh0B) ___ ### Exercise - `is_int_key` In `VectorMap` write a class constant `is_int_key` that holds a boolean value. It should be `true` when the key is `int` and `false` otherwise. Generally, it should do the same job as the `isIntKey()` method, but we want to have it available even without having an object. Take a look in the `` library for that. It should be useful 🙂