【问题标题】:C++: How to create object factory for runtime template parameters?C++:如何为运行时模板参数创建对象工厂?
【发布时间】:2014-04-29 03:16:13
【问题描述】:

我想创建一个整数到模板类对象的映射。模板参数是一个整数,模板参数的值在编译时是未知的

我已经看到了这个问题:C++: Passing a variable as a template argument,它有帮助,但我还是有点卡住了。我试图避免switch/case 声明;我不想写很多cases。

我下面的示例无法编译,但它触及了我正在尝试做的事情。有人可以帮我完成这个吗?

#include <iostream>
#include <map>

class File{
    public:
        File(int MF): mf(MF) {  }
        int mf;
};

template <int MF>
class tFile: public File{
    public:
        tFile(): File(MF){   }
        void print() { std::cout << "MF=" << MF << std::endl;}
};

File* createMF0(){
    return new tFile<0>;
}
File* createMF1(){
    return new tFile<1>;
}
File* createMF2(){
    return new tFile<2>;
}
File* createMF3(){
    return new tFile<3>;
}

int main(){

    std::cout << "\nI'm learning about templates." << std::endl;

    File myFile(3);
    std::cout << "\nmyFile  has MF=" << myFile.mf << std::endl;

    tFile<4> myTFile;
    std::cout << "myTFile has ";
    myTFile.print();

    // Now for the real stuff
    std::map<int, std::function<File*>> createMF;
    std::map<int, File*> templateFiles;

    createMF[0] = createMF0;
    createMF[1] = createMF1;
    createMF[2] = createMF2;
    createMF[3] = createMF3;

    // Here I'm trying to avoid a switch statement
    std::cout << std::endl;
    for (int i=0; i <= 3; i++){
        std::cout << "i = " << i << std::endl;
        templateFiles[i] = createMF[i]();
    }

    return 0;
}

【问题讨论】:

  • 我对您的 API 感到有些困惑,为什么您基本上将 File(int) 包装在模板中?您将永远无法在 C++ 中生成使用在编译时完全未知的值的模板,因为这违背了模板的全部意义,即在编译时为每个模板参数生成专门的代码。如果@RSahu 在下面的回答有效,那么您实际上并没有依赖于运行时值的模板,您只是没有使用正确的模板。
  • 嗯,这是我想要完成的一个简化示例。 @RSahu 的回答确实有效。我打算在我的真实代码中进行模板专业化。我的 C++ 生锈了;我愿意倾听和学习他人的专业知识。

标签: c++ templates runtime


【解决方案1】:

换行

std::map<int, std::function<File*>> createMF;

std::map<int, std::function<File*()>> createMF;

用于实例化std::functional 的模板参数类型不是File*,而是一个没有参数并返回File* 的函数。

更新

您可以使用其他模板稍微简化代码。而不是

File* createMF0(){
    return new tFile<0>;
}
File* createMF1(){
    return new tFile<1>;
}
File* createMF2(){
    return new tFile<2>;
}
File* createMF3(){
    return new tFile<3>;
}

你可以只有一个功能:

template <int N>
File* createMF(){
    return new tFile<N>;
}

如果这样做,main函数的核心需要更改为:

// Now for the real stuff
std::map<int, std::function<File*()>> createFunctions;
std::map<int, File*> templateFiles;

createFunctions[0] = createMF<0>;
createFunctions[1] = createMF<1>;
createFunctions[2] = createMF<2>;
createFunctions[3] = createMF<3>;

// Here I'm trying to avoid a switch statement
std::cout << std::endl;
for (int i=0; i <= 3; i++){
    std::cout << "i = " << i << std::endl;
    templateFiles[i] = createFunctions[i]();
}

【讨论】:

  • 这很好用。至少它编译得很好。我的方法是解决这个问题的正确方法吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多