C++按类型组与基本类型组合的模板专用化

C++ template specialization by type groups combined with basic type

本文关键字:类型 专用 组合 C++      更新时间:2023-10-16

我想按类型组以及一些特定简单类型的额外定义来专门化模板。在 C++11 中并提升 1.60 可能吗?以下伪代码说明了我的意图:

template <typename T> // Universal definition
struct convert
{  ...  }
template <> /* Definition for integral types like defined by std::type_traits */
struct convert<integral_types>
{  ...  }
template <> /* Definition for floating point types like defined by type_traits */
struct convert<floating_types>
{  ...  }
template <> /* Exception from integral types - specific definition */
struct convert<char>
{  ...  }

我认为这可以通过标签调度程序解决,但我不确定这是否是最佳解决方案。另一种选择是enable_if,结合is_integral(和类似的组),但简单的char类型是问题...

你可以做这样的事情:

template <typename T, typename Enabler = void> // Universal definition
struct convert
{  ...  };
template <typename T> /* Definition for integral types like defined by std::type_traits */
struct convert<T, std::enable_if_t<std::is_integral<T>::value>>
{  ...  };
template <> /* Exception from integral types - specific definition */
struct convert<char, void>
{  ...  };

这是不使用std::enable_if_t的替代解决方案:

// g++ -Wall -std=c++11 -o typetraitstest typetraitstest.C
#include <iostream>
#include <type_traits>
#include <cstdint>
template <typename T, bool isFloatingPoint, bool isSigned>
struct _Numeric;
template <typename T>
struct _Numeric<T, true, true>
{
  void doit() { std::cout << "FloatingPoint " << sizeof (T) << " byten"; }
};
template <typename T>
struct _Numeric<T, false, true>
{
  void doit() { std::cout << "SignedInt " << sizeof(T) << " byten"; }
};
template <typename T>
struct _Numeric<T, false, false>
{
  void doit() { std::cout << "UnsignedInt " << sizeof(T) << " byten";  } 
};
template <>
struct _Numeric<char, false, true>
{
  void doit() { std::cout << "special case charn"; }
};
template <typename T>
struct Numeric :
  _Numeric<T, std::is_floating_point<T>::value, std::is_signed<T>::value>
{};
  
int
main()
{
  Numeric<float> f;
  Numeric<int32_t> i32;
  Numeric<uint64_t> u64;
  Numeric<char> c;
  
  f.doit();
  i32.doit();
  u64.doit();
  c.doit();
  return 0;
}

这是输出(请注意,char似乎是签名的):

% ./typetraitstest
FloatingPoint 4 byte
SignedInt 4 byte
UnsignedInt 8 byte
special case char