我有一个与(我认为)C++(C++11 之前的版本,我现在无法升级)模板编程(和“特征”)相关的问题。
我的目标:
我有不同的(但非常相似)类(已经从具有新功能和成员的基类派生类)。
我编写了一个模板类,它继承自这些类中的任何一个,并使用多态函数“open”从数据库中获取与特定类相关的所有成员和信息。
我想到这个策略是因为我想使用这个实例化的类(及其所有成员)作为其他函数的输入。 我本可以使用 switch/case 架构来做到这一点(我认为..但这里我的模板类可以从模板参数中的类继承......),但我想在这里避免它,因为它之后已经被大量使用。
例如,我有类 Derived1 和 Derived2 (在 Derived.hpp 文件中定义),它们覆盖其 Root 父类的 open 函数。 我有一个模板函数 MyClass 曾经使用过 MyClass < DerivedType1> currentClass(),或者 MyClass < DerivedType2> currentClass() 执行我想要的操作(代码如下)。
问题:
是否可以写一些让我可以创建 for 循环的东西?
类似的东西
For (auto i=1; i<N; ++i)
{
MyClass<DerivedType[i]> currentClass();
--- other things to do with my currentClass ---
}
现在对我来说,我的 DerivedType 是“类型”(请参阅下面的 Traits.hpp 片段中的结构),我什至不知道是否可以将它们放入容器中(如向量)...... 也许在 C++11 中我可以为所有 DerivedTypes 定义一个枚举类(这是真的吗?),但这里使用 C++03?
完全迷失了,我承认……
非常感谢您的任何建议。
(工作)主要
(包括“MyClass.hpp”)
int main(int, char* [])
{
GlobalClass GlobalItem(); //global class encapsulating all the info of each item from the database
//connection to the database
//DerivedType1 case
MyClass<DerivedType1> CurrentClass();
GlobalItem.AddCurrentClass();
//with a for loop or the like I can use the fact that at each loop the class is declared only inside the { … } and then each time the destructor
//is automatically called
CurrentClass.clear();
CurrentClass = MyClass<DerivedType2>();
GlobalItem.AddCurrentClass();
return 0;
}
这是模板类MyClass.hpp:
(包括“traits.hpp”)
template <class Traits>
class MyClass : public Traits::type
{
private:
typedef typename Traits::type BaseType;
protected:
std::string currentType_;
public:
//constructor
MyClass() : BaseType() { this->open() }
//destructor
virtual ~MyClass();
};
这里是由范围 :: 运算符运行的 Traits.hpp 文件
(包括“Derived.hpp”)
struct DerivedType1 {
typedef Derived1 type;
};
struct DerivedType2 {
typedef Derived2 type;
};
模板在编译时实例化,
for()
循环在运行时评估。要在模板定义上“循环”,您可以拥有像这样的结构
template<int N>
struct A {
typedef A<N - 1> X;
};
template<>
struct A<0> {
typedef void X;
};
使用可变参数模板,您可以执行以下操作:
template <typename T>
void do_job()
{
// job for one type
// MyClass<T> currentClass;
// ...
}
template <typename ... Ts>
void do_jobs()
{
// trick to unroll the types sequentially
std::initializer_list<int>{(do_job<Ts>(), 0)...};
// In C++17, it becomes simply:
// (do_job<Ts>(), ...);
}
并称之为:
do_jobs<Derived1, Derived2>();