有没有办法解决c ++不支持运行时模板的事实?

时间:2011-12-18 19:09:56

标签: c++ templates

我有一个模板类,可以获得两个模板参数。

template <class T,class A>
class Z{...};

假设我有四种类型的T,而A的数量相同。所以,有 16 选项!

如果我想在运行时选择其中一个,我需要写一个巨大且令人作呕的案例。

我知道C ++不支持运行时模板。

还有其他办法吗?

5 个答案:

答案 0 :(得分:3)

不,确实没有。模板的本质是固有的,这完全是完全不可能的。

答案 1 :(得分:3)

实现某种类似的方法是将依赖项添加到class Z并在运行时提供这些依赖项 - 这被称为Strategy pattern

当然这意味着class Z不再模仿所有这一切。但实际上没有办法让你的馅饼吃掉它:模板是一个编译时构造,而你正在询问在运行时配置某些东西的方法。您不能在运行时配置类型,只能配置对象。

答案 2 :(得分:0)

我不是说这是一个很好的解决方案,但我已经看到它在过去实现了:你可以在模板资源文件中保存模板化类的代码并在运行时编译它进入可插拔模块!

顺便说一句,我建议重构问题,以便不需要实例化MN模板,而只需要M + N;我不知道这在你的问题中是可能的,但它通常是,例如,如果要从一种类型转换为另一种类型,通常可以引入适用于所有类型的中间表示。你仍然需要一个案例或一种形式的多态来处理各种类型,但这是不可避免的。

答案 3 :(得分:0)

虚拟类在运行时为您提供在编译时为您提供的模板。种类。

编写时的模板代码不是真正的代码,只是可用于生成代码的模板。每次你使用它..它通常会在那里生成代码。例如

Z<int, std::string> z; // At this point a new class called Z<int, std::string> is defined, then the code to instantiate it at run time is generated.

这可能是一个有用的读物​​:c++ standard practice: virtual interface classes vs. templates

也许这就是你所追求的?使用多态和虚拟类的类似事情..

class Z{
public:
    virtual void doSomething();
};

class ZT : public Z {
public:
    void doSomething();
};

class ZA : public Z {
public:
    void doSomething();
};

...

void useClasses(Z* ptr) {
    ZT* ztPtr = dynamic_cast<ZT*>(ptr); // Runtime conversion
    if (ztPtr) {
         // do specific stuff for this type
    } else {
         ptr->doSomething(); // generic behaviour that'll call whichever class ptr actually is
    }
}

答案 4 :(得分:0)

这可能符合您的需求,也可能不符合您的需求,但简单的通用界面听起来像您想要的那样:

class Z_interface{ //abstract interface
public:
    virtual ~Z_interface() {} //virtual destructor
    virtual void func()=0; //virtual member
};

template <class T,class A>
class Z : public Z_interface { //implimentation
public:
    virtual ~Z_interface() {}
    virtual void func() {}
};

int main() {
    std::unique_ptr<Z_interface> ptr;
    switch(stuff) { //make the correct type
    case 0: ptr = std::unique_ptr<Z_interface>(new Z<int, char>()); break;
    case 1: ptr = std::unique_ptr<Z_interface>(new Z<int, short>()); break;
    case 2: ptr = std::unique_ptr<Z_interface>(new Z<long, char>()); break;
    case 3: ptr = std::unique_ptr<Z_interface>(new Z<long, short>()); break;
    };
    ptr->func(); //don't care about the type anymore, just the algorithms
}