混合别名和模板特化

Mixing aliases and template specializations

我正在寻找最好的方法来获得一种 "object" 可以专门化或 "linked" 到另一种类型。

例如,你不能特化一个 class 使其成为一个简单的 int,你也不能使用关键字 using 来特化 classes。

我的解决方案如下:

template<class Category, Category code>
struct AImpl
  {};

template<class Category, Category code>
struct AHelper
  {
  using type = AImpl<Category, code>;
  };

template<class Category, Category code>
using A = typename AHelper<Category, code>::type;

template<int code>
void doSomething(A<int, code> object)
  {
  }

template<>
struct AImpl<int, 5>
  { 
  double a; 
  };

template<>
struct AImpl<int, 6>
  { 
  int b; 
  double c;
  };

template<>
struct AHelper<int, 7>
  {
  using type = int;
  };

template<class Category, Category code>
struct Alternative {};

template<int code>
void doSomethingAlternative(Alternative<int, code> object)
  {
  }

这可行,但您需要在 doSomething 中指定代码参数,我想避免这种情况。

例如:

A<int,7> a7; // This is equivalent to int
a7 = 4;
A<int, 5> a5; // This is equivalent to AImpl<int,5>
a5.a = 33.22;
doSomething(a5); // This does not compile
doSomething<5>(a5); // This compiles but is bulky
Alternative<int,0> alt0;
doSomethingAlternative(alt0); // This compiles and is not bulky
                              // but you're forced to use class
                              // specializations only

有没有办法实现我想要的?可以同时更改 doSomething 或 A 实现。

如果您尝试根据调用它的类型自定义 doSomething 的行为,您不能让编译器从 AHelpr::type 中推导出内容(如之前的 ). But you can tell it what it needs to know by providing a customization point in the form of traits。例如:

template<typename T>
void doSomething(T& object)
{
    auto code = SmthTriats<T>::code;
}

考虑到专业化的能力,这是高度可扩展的 SmthTriats:

template<typename> struct SmthTriats;

template<typename Category, Category code_>
struct SmthTriats<AImpl<Category, code_>> {
    static constexpr auto code = code_;
};

template<>
struct SmthTriats<int> {
    static constexpr auto code = 7;
};

特征 class 也允许在模块外进行自定义。客户代码只需要专门化 SmthTriats 他们自己的类型,只要他们尊重你为你的特质制定的合同,你的代码就会为他们工作。