Can a template parameter's default argument be specialized?

c++, template-specialization, templates, traits

Solution

Well, a not-necessarily-prettier one-liner:

#include <type_traits>

template <typename Key,
          typename Value = typename std::conditional<std::is_same<Key, Special>::value, float, int>::type>
class Association { /* ... */ };

Problem

In C++, if I have a template parameter, how can I cleanly specialize a default argument? For example, consider the following: ``` template <class Key, class Value = int > class Association; ``` What if I want `Value` to instead default to `float` for class `Special`? Is there a way to in effect specialize the class `Association` such that if Key is `Special` that Value defaults to instead be `float`? I imagine one way to do this would be with traits: ``` template <class Key> struct Traits { typedef int defaultValue; } template<> struct Traits<Special> { typedef float defaultValue; } template <class Key, class Value = Traits<Key>::defaultValue> class Association; ``` Is there a more succinct way of doing this that is not so involved and would more readily show that int is the normal default at the place where Association is defined?

Original source