2015-04-04 76 views
0

我经常遇到与SubType Polymorphism相关的问题,我正在寻找一个我可能不知道的优雅解决方案。调用基于运行时逻辑的模板化C++方法

下面是一个简单的继承层次:

struct BaseClass { 
    virtual ~BaseClass() = 0; 
    std::string name; 
}; 

template <T> 
struct DerivedClass 
{ 
    DerivedClass(const std::string& _name): name(_name) { } 
}; 

现在,我可能会产生很多不同的名字和模板类型,这些DerivedClass实例并使用他们的BaseClass它们存储在阵列中。

std::vector<BaseClass*> array; 
array.push_back(new DerivedClass<TABC>("abc")); 
array.push_back(new DerivedClass<TDEF>("def")); 
... 

这是非常标准的运行时多态性。

然而,当我有功能的新层的类型是专用的添加和不希望这个新层在两个方向耦合,我最终不得不做这样的事情:

template <typename T> 
void method(DerivedClass<T>* object) { } 

void callMethod(BaseClass* object) 
{ 
    // this is the logic I'm trying to move up a layer 

    if (object->name == "abc")  method<TABC>(object); 
    else if (object->name == "def") method<TDEF>(object); 
} 

这些方法中的每一个都必须具有相同的运行时字符串列表才能进行编译时类型转换,这意味着添加新类型需要进行大量更改。

如果我假定新图层只支持编译时已知的特定选项(就像这里的情况一样),那么在运行时添加新类型是可行的,但不能使用它们在这一层,这将是很好的。我现在的想法是,如果我将虚拟方法引入带有函数指针的类层次结构中,我可以根据特定的编译时类型为第二层中的每个方法注册函数指针(理想情况下只指定一次),有点像双调度类型的方法。

有什么想法,建议吗?

+0

为什么你不能将模板移动到基地? – 2015-04-04 14:48:02

+0

我确实需要能够一般性地存储这些数据,因此我可以在其他用例中使用多态性。 – Dan 2015-04-04 15:21:34

回答

3

你需要一个链接调用基于字符串的特定模板版本,你能做的最好是有string词典 - >lambda function和使用字符串作为查找得到function<>打电话。这避免了嵌套的if,并且在编译时(缺省列表)和运行时(任何更改只是数组更改)都相对容易维护。

+0

谢谢,这符合我的想法。问题是如何建立这些列表。如果我有多个这样的字符串 - >函数列表,我只想真的想指定我曾经使用的函数和类型一次,然后执行所有的映射来构建所有的排列组合? (也不能在这个应用程序中使用C++ 11)。 – Dan 2015-04-04 15:20:09

+0

使用宏来构建函数对象,并在函数名称中插入模板参数以确保唯一性。 Lambda函数只不过是没有名字的正常函数(即编译器生成的名称)。然而,你应该重新考虑你的任意限制,C++ 11是4岁。如果你现在不能使用它,你什么时候可以? – Blindy 2015-04-04 21:48:52