开发者

match multiple types for template specialization resolution

开发者 https://www.devze.com 2023-04-02 05:58 出处:网络
Briefly dismiss the fact that normal function overloading will serve this example better. It is meant only as a way to learn about template programming. Having said that, you are welcome to comment on

Briefly dismiss the fact that normal function overloading will serve this example better. It is meant only as a way to learn about template programming. Having said that, you are welcome to comment on the benefits/differences you'll get from using function overload, compared to function template specialization (although that might deserve a question of its own).


Consider the following example:

template <typename T>
inline void ToString(T value, char* target, size_t max_size );

template <>
inline void ToString<float>(float value, char* target, size_t max_size)
{
   snprintf( target , max_size , "%f" , value);
}

template <>
inline void ToString<double>(double value, char* target, size_t max_size)
{
    snprintf( target , max_size , "%f" , value);
}

Is there a way to write only one of these specializations that match both float and doub开发者_如何学编程le types?

Basically I envision writing a template specialization for a template type that will match both float and double (as sort of 'float or double' type matcher) but I'm not sure whether that is possible at all with C++. That said, I've seen unexpected template magic happen in front of my eyes before, so I think it's a good question to ask here.


Here's a standard solution idiom:

#include <type_traits>
#include <cstdio>


// Helper class

template <typename T>
struct Printer
{
  static typename std::enable_if<std::is_floating_point<T>::value, int>::type
  print(T x, char * out, std::size_t n)
  {
    return std::snprintf(out, n, "%f", x);
  }
};

// Convenience function wrapper

template <typename T> int print(T x, char * out, std::size_t n)
{
  return Printer<T>::print(x, out, n);
}

void f()
{
  char a[10];

  Printer<double>::print(1.2, a, 10);  // use helper class
  print(1.4f, a, 10);                  // wrapper deduces type for you
}

You'll get a compile-time error if you call either construction with a non-floating type. Beware though that this might erroneously work for long doubles, which require the %Lf format specifier; and also recall that floats get promoted to doubles when passed through variadic function arguments.

0

精彩评论

暂无评论...
验证码 换一张
取 消