c++ - 动态选择模板特化

标签 c++ templates c++03

我有一个模板类 Filter ,它采用另一个模板类的实例 Model作为它的参数。我现在想要一个 vector不同模型(即 Model 具有不同模板参数),并能够运行 Filter在他们每个人之上。为此,我得出 Model来自非模板 class AbstractModel ,这让我可以将这些不同的模型放入一个 vector 中.一切都很好,但是有一个问题:调用模板类的方法需要静态知道模板参数。但我没有静态知道它们。

这是代码

#include <vector>
#include <cstdlib>

class AbstractFilterData {};
class AbstractModel {};
template<int N>
class Args {};

template<int N>
class FilterData : public AbstractFilterData
{ int a; };

template<int N>
struct Model : public AbstractModel
{
    static const int n=N;
    virtual void compute(Args<N>& args) const = 0;
};

struct ModelA : public Model<3>
{
    virtual void compute(Args<3>& args) const {}
};

struct ModelB : public Model<5>
{
    virtual void compute(Args<5>& args) const {}
};

template<int N, int P>
struct Filter
{
    static void predict(FilterData<N>& data, const Model<N>& model)
    {
        Args<N> args;
        model.compute(args);
    }
};

int main()
{
    // For statically-defined model this works OK
    FilterData<ModelA::n> data;
    ModelA modA;
    Filter<ModelA::n,2>::predict(data, modA);

    // Let's make a bunch of different models and put them into a vector
    std::vector<AbstractModel*> models;
    models.push_back(new ModelA);
    models.push_back(new ModelB);

    // Associated data for these models
    std::vector<AbstractFilterData*> fdata;
    fdata.push_back(new FilterData<ModelA::n>);
    fdata.push_back(new FilterData<ModelB::n>);

    for(size_t i=0; i<models.size(); ++i)
    {
        // Now I'd like to run Filter::predict() on
        // each of the models in the vector... but how?
        Filter<models[i]->n,2>::predict(*fdata[i], *models[i]);
        // This breaks on models[i]->n being not a constant-expression, of course
    }
}

我可以考虑对可能的值进行循环 k模型的模板参数,试图做 dynamic_cast(models[i],Model<k>*) , 调用 Filter<k,2>::predict()然后,但这看起来很丑陋。另外,因为我不知道 k 的上限,我不得不猜测,因为制作 INT_MAX Filter 的实例化会使代码无法使用。

另一种方法是将静态 const 指针指向 Filter<N,2>::predict() Model<N> 中的方法声明,但这也很丑陋,因为那时类 Model似乎与类 Filter 相关联,这打破了这些类的独立性(例如,添加另一个过滤器不仅有效)。

是否有更好的方法来遍历这些不同的模型集并调用 Filter<?,2>::predict()在他们?理想情况下,我希望编译器为我完成所有分派(dispatch)工作,这样就不会为从未真正使用过的参数进行模板实例化。

最佳答案

这是伪代码,省略了很多东西。

class AbstractModel {
    virtual int Order() = 0;
};
class AbstractModel {
    virtual int Order() = 0;
};

template<int N>
class FilterData : public AbstractFilterData {
    virtual int Order() { return N; };
}
template<int N>
class Model : public AbstractModel {
    virtual int Order() { return N; };
}

multimap<int, AbstractFilterData*> dataMap; // dataMap[i] contains a pointer to 
                                            // FilterData<i> 
multimap<int, AbstractModel*> modelMap;     // modelMap[i] contains a pointer to 
                                            // Model<i>

现在您可以做很多事情。您可以将 AbstractFilterData* 传递给您的 compute,它会根据需要向下转换参数。您可以将整个 dataMap 传递给 compute,它会获取并向下转换所需的数据。您可以在只有模板成员的类中隐藏 dataMap

template <int N>
void Put(FilterData<N>);
template <int N>
FilterData<N> Get();  // or perhaps FilterDataIterator<N>, if you really
                      // need a multimap

并自己进行所有的转换,并传递给那个类。或者你可以颠倒整个事情并用 modelMap 做同样的事情。

关于c++ - 动态选择模板特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24365282/

相关文章:

c++ - 编译样例opencv kalman滤波程序时出现链接错误

java - 为什么在这种情况下,我的 Java 代码比我的 C++ 代码运行得更快?

c++ - 对模板参数推导感到困惑

c++ - 使用 SFINAE 检测某物是否在( boost )范围内

C++从编译时多态性中隐藏模板习语

c++ - 在生产中使用 Address Sanitizer 或其他未定义的行为 sanitizer ?

c++ - 关于非局部静态初始化的规则是什么?

c++ - 提供特征类的类型的模板特化

c++ - 如何学习c++泛型编程和模板?

c++ - 使用 SFINAE 检测 constexpr