C++:如何为运行时模板参数创建对象工厂

C++: How to create object factory for runtime template parameters?

本文关键字:参数 创建对象 工厂 运行时 C++      更新时间:2023-10-16

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

我看到过这样一个问题:C++:将变量作为模板参数传递,这很有帮助,但我仍然有点停滞不前。我试图避免switch/case语句;我不想写很多case

我下面的例子没有编译,但它触及了我想要做的事情的核心。有人能帮我完成这个吗?

#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;
}

更改行

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]();
}