Indeed, in C ++ vanilla, you either write manually for certain types, or use a template like dirkgently.
However, if you can use Boost, this does what you want:
template <class T> StreamLogger& operator<<(T val) { typedef boost::mpl::vector<const char*, int, unsigned, size_t> allowed_types; BOOST_MPL_ASSERT_MSG(boost::mpl::contains<allowed_types, T>::value, TYPE_NOT_ALLOWED, allowed_types); // generic implementation follows elements.push_back(boost::lexical_cast<std::string>(val)); return *this; }
This will create a compile-time error with the TYPE_NOT_ALLOWED message embedded in it if the compiled type is not in the type list.
Also, since Boost is required for this answer, I just used lexical_cast . You will notice that you are repeating this code, and this is bad. Consider wrapping this functionality in a function.
If you cannot use Boost, you can easily imitate this with some traits like:
template <typename T, typename U> struct is_same { static const bool value = false; }; template <typename T> struct is_same<T, T> { static const bool value = true; }; template <bool> struct static_assert; template <> struct static_assert<true> {};
It will also generate a compile-time error if the statement is not executed, although the code is not so sexy.: (<- Not sexy
GManNickG
source share