模板的 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>::Opposite
与 Down
不是同一个模板,至少现在还不是 - 语言规则将来可能会更改,更多详细信息请参见 及其评论。
如果您想使用特征从 oneDirection<Direction_traits<Up>::Opposite>
内部返回到 Up
,这可能会导致问题 - 不会为别名模板定义特征特化。事情需要变得更复杂一些才能允许这样的使用;上面引用的答案中概述了一个可能的解决方案。
我正在尝试为模板而不是类型创建别名,但我找不到执行此操作的语法。下面是一个演示我的问题的例子。我的猜测是这只是无法完成的事情,但我希望有人能证明我错了。如果做不到,是否有一些潜在的原因导致这样做没有意义,或者只是没有实施?
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>::Opposite
与 Down
不是同一个模板,至少现在还不是 - 语言规则将来可能会更改,更多详细信息请参见
如果您想使用特征从 oneDirection<Direction_traits<Up>::Opposite>
内部返回到 Up
,这可能会导致问题 - 不会为别名模板定义特征特化。事情需要变得更复杂一些才能允许这样的使用;上面引用的答案中概述了一个可能的解决方案。