c++ - 模板参数提取和修改
问题描述
我编写了以下类来提取类的模板参数并在编译时Base
将类的模板参数附加到它:Derived
template <typename...> struct derived_type_traits;
// specialization for the case when Base is not a template
template <typename Base> struct derived_type_traits<Base> {
template <template<typename...> class Derived, typename... DerivedArgs>
using type = Derived<DerivedArgs...>;
};
// specialization for the case when Base is a template
template <template <typename...> class Base, typename... BaseArgs> struct derived_type_traits<Base<BaseArgs...>> {
template <template<typename...> class Derived, typename... DerivedArgs>
using type = Derived<DerivedArgs..., BaseArgs...>;
};
我将它用作工厂构建模块的一部分。使用这个特征类,我可以Derived
从一组模板参数和一个Base
类中构造一个:
namespace A {
class Base {};
template <typename T>
class Derived : public Base {};
auto ptr = new typename derived_type_traits<Base>::type<Derived, int>();
}
namespace B {
class Base {};
template <typename T1, typename T2, typename T3>
class Derived : public Base {};
auto ptr = new typename derived_type_traits<Base>::type<Derived, int, double, std::string>();
}
namespace C {
template <typename T>
class Base {};
template <typename T1, typename T2, typename T3, typename T>
class Derived : public Base<T> {};
auto ptr = new typename derived_type_traits<Base<int>>::type<Derived, int, double, std::string>();
}
但是,它不适用于以下情况:
namespace D {
template <typename T>
class Base {};
template <typename T1, typename T2, template <typename,typename> class T3, typename T>
class Derived : public Base<T> {};
template <typename T1, typename T2> struct Foo {};
auto ptr = new typename derived_type_traits<Base<int>>::type<Derived, int, double, Foo>();
}
namespace E {
template <typename U1, template <typename,typename> class U2>
class Base {};
template <typename T1, typename T2, typename T3, typename U1, template<typename,typename> class U2>
class Derived : public Base<U1,U2> {};
template <typename T1, typename T2> struct Foo {};
auto ptr = new typename derived_type_traits<Base<int, Foo>>::type<Derived, int, double, std::string>();
}
测试代码在这里。
我知道这与可变参数模板无法匹配类型和模板类型的混合这一事实有关。
有解决方案还是我走错路了?我最多可以使用 C++14(没有 C++17)。
解决方案
您是元元编程,而 C++ 并不真正支持这一点。这也是一个值得商榷的计划,有点像三星级节目。
如果你想元元编程,你将不得不限制你的元编程更加统一。把一切都变成类型。
使用std::integral_constant
类型来传递值(甚至适用于函数指针!)。利用
template<template<class...>class Z>struct ztemplate
传递模板。
或者(或另外)转向基于价值的元编程。将类型作为值传递template<class>struct tag_t
,模板被替换为从标签映射到标签的对象或函数等。
这两种方法都允许在更高程度上更容易和更简单的递归元编程。
在原始 C++ TMP 中执行此操作会遇到这个问题,还有一堆烦人的规则最终会让你失望(比如将包传递给 1 个参数模板)和平庸的编译器支持。
最后,请注意,在您的具体情况下:
template <typename T1, typename T2, typename T3, typename U1, template<typename,typename> class U2>
class Derived : public Base<U1,U2> {};
比:
template <typename T1, typename T2, typename T3, class Base>
class Derived : public Base {};
auto ptr = new Derived< int, double, std::string, Base<int, Foo>>();
推荐阅读
- php - 保存在条目 0 中的数组长度?
- android - 未使用 Actionbar 时未调用 onSupportNavigateUp
- ios - 无法访问 AppStore 连接
- task - FreeRtos 从 IRQ 调用 vTaskDelete
- linux - 是否可以在具有 2 个不同驱动程序的 x86 设备上绑定 2 个相同的设备?
- sqlalchemy - SQLAlchemy 与附加列的条件多对多关系
- python - 如何解决 - IOERROR:致命错误:文件“路径/到/文件”无法定位或不可读
- python-3.x - 如何在不使用 Pandas 的情况下创建等效于 numpy.nan 的日期时间对象?
- apache-spark - sqoop 使用按字符或字符串拆分?
- javascript - 使用对象数组的所有字段进行字符串搜索