C++ 混合别名和模板专门化

C++ 混合别名和模板专门化,c++,c++11,templates,template-meta-programming,template-argument-deduction,C++,C++11,Templates,Template Meta Programming,Template Argument Deduction,我试图找到最好的方法来拥有一种“对象”,它可以是专门化的,也可以“链接”到另一种类型 例如,不能专门化一个类以使其成为简单int,也不能使用关键字using专门化类 我的解决方案如下: template<class Category, Category code> struct AImpl {}; template<class Category, Category code> struct AHelper { using type = AImpl<Ca

我试图找到最好的方法来拥有一种“对象”,它可以是专门化的,也可以“链接”到另一种类型

例如,不能专门化一个类以使其成为简单int,也不能使用关键字using专门化类

我的解决方案如下:

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)
  {
  }
模板
结构AImpl
{};
模板
结构AHelper
{
使用类型=AImpl;
};
模板
使用A=typename AHelper::type;
模板
空位(物体)
{
}
模板
结构AImpl
{ 
双a;
};
模板
结构AImpl
{ 
int b;
双c;
};
模板
结构AHelper
{
使用type=int;
};
模板
结构替代{};
模板
void dosomethingalerative(替代对象)
{
}
这是可行的,但您需要在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
template<typename T>
void doSomething(T& object)
{
    auto code = SmthTriats<T>::code;
}
a7;//这相当于int
a7=4;
A a5;//这相当于AImpl
a5.a=33.22;
剂量测定法(a5);//这是不可编译的
剂量测定法(a5);//这可以编译,但体积庞大
备选方案0;
剂量霉素替代品(alt0);//这是可编译的,并不笨重
//但你不得不使用课堂
//专门化

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

如果您试图根据调用的类型自定义
doSomething
的行为,则编译器无法从
AHelpr::type
中推断内容(如前所述)。但是您可以通过以的形式提供定制点来告诉它需要知道什么。例如:

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
template<typename T>
void doSomething(T& object)
{
    auto code = SmthTriats<T>::code;
}

traits类也允许在模块外进行自定义。客户机代码只需对SMTHTriat的类型进行专门化,只要他们尊重您与您的特质达成的契约,您的代码就可以为他们工作。

您的代码中没有模板专门化。我不清楚除了您展示的具体实现之外,这里的总体目标是什么。我假设您希望以后能够调出
AImpl
,但不清楚为什么不直接通过
使用A=AImpl1
进行调出。换句话说,
AHelper
的意义是什么?在您展示的代码中,这似乎不是必需的,因此您是否可以扩展示例以包括
AHelper
部分的用途(这似乎是问题的核心)?@MaxLanghof如果您是对的,代码已更改。我希望现在更清楚,我添加了一些其他代码来向您展示替代方案。出于明显的原因,您省略了
doSomething
的实现,但是对于基本类型和类类型来说,哪种代码的工作方式完全相同?对于一个纯整数,在这样一个函数中如何需要
类别
?有趣的是,这在C++11中也能工作吗?但我认为这和我所寻找的有所不同though@Saturnu-当然。特征的概念几乎和C++模板一样古老。标准库本身大量使用它们。它们是提供有关类型(或类型族,在部分专门化的情况下)的有趣属性的方便方法。如果您希望使您最初的尝试起作用,我建议您不要专注于解决方案。在您的代码库中尝试一下。这项技术之所以成为行业标准,有一个很好的理由。@Saturnu-这里是另一种思考它的方式<代码>帮助者确实是一种特质(一种类型的映射)。编译器不能假设映射是双向的(如上所述)。你需要告诉它如何通过另一个特征反向映射。@Saturnu-我明白你的意思。是的,修正了这个特征。