如何测试类型参数是否为模板类型
How to test if a type parameter is a template type
假设我有一个这样的模板类:
template < typename TParam >
class Test
{
// content
};
我想拉出TParam
的第一个模板参数,如果它是类模板的专用化。像这样:
template < typename TParam >
class Test
{
using TParamInner = TemplateType<TParam>::Type;
// use TParamInner here
};
附加信息:
- 我可以访问所有C++98。
- 我可以访问 C++11 的子集。
- 如果可能的话,我宁愿避免使用stdlib(假设这是因为我使用的是没有 stdlib 可用的嵌入式系统和/或因为我的内存受到严重限制)
你可以用这样的东西接近:
template <class >
struct first_template_param;
template <template <class...> class Z, class T, class... Ts>
struct first_template_param<Z<T, Ts...>> {
using type = T;
}
它不会处理采用非类型模板参数的std::array
或任何其他类模板。但它将处理所有"普通"类模板。然后,您可以随时为所需的所有专业添加额外的专业化:
template <class T, size_t N>
struct first_template_param<std::array<T,N>> {
using type = T;
}
感谢@Barry推动解决方案。
这不是所有模板类型的完整答案,但它适用于所有参数都是类型的模板,这是大量最有用的模板。
template < typename Head, typename ... Tail >
struct split { using first = Head; };
template <class >
struct cls_template_info; // fails on non-templates
template <template <class...> class Z, class... Ts>
struct cls_template_info<Z<Ts...>>
{
using type = typename split<Ts...>::first; // typename used to disambiguate
};
然后可以将其用作using T = cls_template_info<std::vector<int>>::first;
。
你不能。 模板类型永远不会传递到运行时。 您必须实例化它(这将导致一个完整的新类型),然后编译器生成所需的代码,使其看起来好像您专门为指定的类型参数定义了。事实上,在旧的编译器中(这在很多时候就已经解决了),当你在几个编译单元中实例化一个泛型类型时,这会导致最终程序中多次重复相同的代码。 但正如我所说,这个问题在很久以前就已经解决了。
相关文章:
- 是否可以初始化不可复制类型的成员变量(或基类)
- 是否可以从int转换为enum类类型
- 检查 std::shared_ptr<> 的当前底层类型是否为 T
- 函数作为模板参数,是否对返回类型强制约束
- JS相等运算符(如===)是否可以使用embind类型
- visual是否可以在c++中创建一个接收无限数量相同类型(或至少相当数量)参数的函数
- 检查函数返回类型是否与STL容器类型值相同
- 在类型和包装器之间reinterpret_cast是否安全<Type>?
- 检查某些类型是否是模板类 std::optional 的实例化
- 是否有内置方法可以强制转换为不同的基础类型,但保留常量限定符?
- C++类型特征,以查看是否可以<uint32_t>对类型"K"的任何变量调用"static_cast(k)"
- boost 是否有按特殊类型值编码状态"compact optional"?
- 初始值设定项列表是否只接受使用相同类型的值初始化变量?
- 是否有任何建议来统一函数类型限定符并简化可恶的函数类型?
- 表达式 SFINAE:如何根据类型是否包含具有一个或多个参数的函数来选择模板版本
- 检查一个类型是否直接派生自"enable if"上下文中的另一个类型(是其子类型)
- 在运行时检查继承是否只有一种类型和 void*
- 给定一个C++嵌套的私有结构类型,是否有从文件范围静态函数访问它的策略
- 将类型声明为类型模板参数的模板参数的一部分是否合法?
- 当返回类型声明为 ListNode 时,我们是否可以返回 false<T>*