模板的 C++ 别名?

C++ Alias to Template?

我正在尝试为模板而不是类型创建别名,但我找不到执行此操作的语法。下面是一个演示我的问题的例子。我的猜测是这只是无法完成的事情,但我希望有人能证明我错了。如果做不到,是否有一些潜在的原因导致这样做没有意义,或者只是没有实施?

template <class S>
class Down;

template <class S>
class Up {
    template <class S1>
    using Opposite = Down<S1>;
};

template <class S>
class Down {
    template <class S1>
    using Opposite = Up<S1>;
};

template <template <typename> class Direction>
void oneDirection() {
    //Call another function here that uses the template argument as a template
}

template <template <typename> class Direction>
void bothDirections() {
    oneDirection<Direction>();
    oneDirection<Direction::Opposite>();  //This doesn't compile
}

int main() {
    bothDirections<Up>();
}

Direction::Opposite 中,Direction:: 是一个 嵌套名称说明符 ,它不能确实表示 class 模板(您需要为其提供所需的模板参数以使其成为模板专业化)。

我想不允许这种形式的一个原因是 class 模板可以有部分或显式特化,它可以提供与主模板不同的成员,因此编译器需要使用特定的特化来能够确切地知道那里有什么。

您可以通过使用特征关联两个模板来解决此问题:

template<class> class Up { };
template<class> class Down { };

template<template<class> class Direction> struct Direction_traits;

template<> struct Direction_traits<Up>
{
   template<class S1> using Opposite = Down<S1>;
};

template<> struct Direction_traits<Down>
{
   template<class S1> using Opposite = Up<S1>;
};

template<template<class> class Direction>
void oneDirection() {
   //Do something here
}

template<template<class> class Direction>
void bothDirections() {
   oneDirection<Direction>();
   oneDirection<Direction_traits<Direction>::template Opposite>();
}

int main() {
   bothDirections<Up>();
}

但是,请记住 Direction_traits<Up>::OppositeDown 不是同一个模板,至少现在还不是 - 语言规则将来可能会更改,更多详细信息请参见 及其评论。

如果您想使用特征从 oneDirection<Direction_traits<Up>::Opposite> 内部返回到 Up,这可能会导致问题 - 不会为别名模板定义特征特化。事情需要变得更复杂一些才能允许这样的使用;上面引用的答案中概述了一个可能的解决方案。