如何访问模板参数自己的模板参数?
How to access the template argument's own template arguments?
假设您有一个 class 模板(例如下面的 second
)。假设 class 模板的模板参数是另一个 class 模板的实例(例如下面的 first
)。你如何访问模板参数自己的模板参数?这可能吗?
这是一些代码:
template<size_t n>
class first {
};
template<typename instantiated_first>
class second {
// would like to be able to access the "n"
// of instantiated_first
};
int main() {
second<first<3>> thing;
return 0;
}
想到三种可能性:
- 重写
first
以将 n
存储为数据成员,或
- 重新设计
second
以继承 first
的实例化 class,以及
- 在两个 class 模板中要求完全相同的模板参数。
我问是因为我不想编辑预先存在的代码(选项 1),并且在我的特定应用程序中,(至少对我而言)考虑 second
真的没有意义作为 first
的一种类型(选项 2)。我将实例化许多 specialized_first
类型的对象,因此 second
到 "own" 这些对象并将它们存储在容器中更有意义。方案3好像也不太时髦
是否有任何我不知道的精美模板功能可以很好地完成此任务?
您声明一个偏特化并从那里选择参数。
template<typename T>
class second<first<T>> {
// T is available here for use.
};
或者更普遍地这样做
template<typename T, typename U
class second<U<T>> {
// T is available here for use.
};
这将匹配具有一个模板参数的所有实例化。
更明智的方法是不将 n
存储为数据成员,而是存储为 static constexpr size_t
,这样它就不会分配任何额外的运行时 space。这是标准且最灵活的机制 - 允许各种其他模板轻松访问此参数。例如,您可以制作一个完全不同的 first
版本,并允许您的 second
在支持原始版本的同时一直使用其他版本,只要所有版本都满足概念接口即可。
同样,每个typename T_
模板参数都可以通过using T = T_;
转发给模板的用户。通常,模板参数是不可访问的,除非您通过将它们声明为类型或将它们的值存储为 constexpr
或其他方式来允许它们。
您可以改造 second
使其接受相同的模板参数,但是使用 first
和此 value/type 的其他模板越多,或者当您突然想要使用 second
作为 first
的替代版本。更好地从根本上解决此类问题。例如,在 std
中,他们所有的模板 classes 都以类似的方式在 class 中声明了所有必要的类型。
假设您有一个 class 模板(例如下面的 second
)。假设 class 模板的模板参数是另一个 class 模板的实例(例如下面的 first
)。你如何访问模板参数自己的模板参数?这可能吗?
这是一些代码:
template<size_t n>
class first {
};
template<typename instantiated_first>
class second {
// would like to be able to access the "n"
// of instantiated_first
};
int main() {
second<first<3>> thing;
return 0;
}
想到三种可能性:
- 重写
first
以将n
存储为数据成员,或 - 重新设计
second
以继承first
的实例化 class,以及 - 在两个 class 模板中要求完全相同的模板参数。
我问是因为我不想编辑预先存在的代码(选项 1),并且在我的特定应用程序中,(至少对我而言)考虑 second
真的没有意义作为 first
的一种类型(选项 2)。我将实例化许多 specialized_first
类型的对象,因此 second
到 "own" 这些对象并将它们存储在容器中更有意义。方案3好像也不太时髦
是否有任何我不知道的精美模板功能可以很好地完成此任务?
您声明一个偏特化并从那里选择参数。
template<typename T>
class second<first<T>> {
// T is available here for use.
};
或者更普遍地这样做
template<typename T, typename U
class second<U<T>> {
// T is available here for use.
};
这将匹配具有一个模板参数的所有实例化。
更明智的方法是不将 n
存储为数据成员,而是存储为 static constexpr size_t
,这样它就不会分配任何额外的运行时 space。这是标准且最灵活的机制 - 允许各种其他模板轻松访问此参数。例如,您可以制作一个完全不同的 first
版本,并允许您的 second
在支持原始版本的同时一直使用其他版本,只要所有版本都满足概念接口即可。
同样,每个typename T_
模板参数都可以通过using T = T_;
转发给模板的用户。通常,模板参数是不可访问的,除非您通过将它们声明为类型或将它们的值存储为 constexpr
或其他方式来允许它们。
您可以改造 second
使其接受相同的模板参数,但是使用 first
和此 value/type 的其他模板越多,或者当您突然想要使用 second
作为 first
的替代版本。更好地从根本上解决此类问题。例如,在 std
中,他们所有的模板 classes 都以类似的方式在 class 中声明了所有必要的类型。