匹配多种类型的模板特化解决方案

lur*_*her 11 c++ templates metaprogramming c++11

简单地驳回正常函数重载将更好地服务于此示例的事实.它仅作为学习模板编程的一种方式.话虽如此,欢迎您评论使用函数重载所带来的好处/差异,与功能模板专业化相比(尽管这可能值得一提.)


请考虑以下示例:

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);
}
Run Code Online (Sandbox Code Playgroud)

有没有办法只编写其中一个匹配两者floatdouble类型的特化?

基本上我设想为模板类型编写一个模板特化,它将匹配两者floatdouble(作为'float或double'类型的匹配器),但我不确定这是否可能与C++一起使用.也就是说,我之前看到过意想不到的模板魔法发生在我眼前,所以我认为这是一个很好的问题.

Ker*_* SB 5

这是一个标准的解决方案成语:

#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
}
Run Code Online (Sandbox Code Playgroud)

如果您使用非浮动类型调用任一构造,则会出现编译时错误.请注意,这可能错误地适用于需要%Lf格式说明符的长双精度; 并且还记得浮点数在通过可变参数函数参数传递时会被提升为双精度数.