|
||||
|
Section 35:
|
[35.8] Huh? Can you provide an example of template specialization that doesn't use foo and bar?
Yes. One of several ways I personally use template specialization is for stringification. I usually use a template to stringify various objects of various types, but I often need to specialize the code for stringifying certain specific types. For instance, when stringifying bools I prefer "true" and "false" over "1" and "0" so I use std::boolalpha when T is bool. Also I often prefer floating point output to contain all the digits (so I can see very small differences, etc.) so I use std::setprecision when T is a floating point type. The end result usually looks something like this:
#include <iostream>
#include <sstream>
#include <iomanip>
#include <string>
#include <limits>
template<typename T> inline std::string stringify(T const& x)
{
std::ostringstream out;
out << x;
return out.str();
}
template<> inline std::string stringify<bool>(bool const& x)
{
std::ostringstream out;
out << std::boolalpha << x;
return out.str();
}
template<> inline std::string stringify<double>(double const& x)
{
const int sigdigits = std::numeric_limits<double>::digits10;
// or perhaps std::numeric_limits<double>::max_digits10 if that is available on your compiler
std::ostringstream out;
out << std::setprecision(sigdigits) << x;
return out.str();
}
template<> inline std::string stringify<float>(float const& x)
{
const int sigdigits = std::numeric_limits<float>::digits10;
// or perhaps std::numeric_limits<float>::max_digits10 if that is available on your compiler
std::ostringstream out;
out << std::setprecision(sigdigits) << x;
return out.str();
}
template<> inline std::string stringify<long double>(const long double& x)
{
const int sigdigits = std::numeric_limits<long double>::digits10;
// or perhaps std::numeric_limits<long_double>::max_digits10 if that is available on your compiler
std::ostringstream out;
out << std::setprecision(sigdigits) << x;
return out.str();
}
Conceptually they all do the same thing: stringify the parameter. That means
the observable behavior is consistent, therefore the specializations
do not confuse callers. However the details for implementing that observable
behavior is slightly different for bool and floating point types, so
template specialization is a good approach.
|
|||