c++ - 在 C++ 中,有没有办法根据输入类是否抽象来定义模板行为?
问题描述
背景:我继承了一个大型系统,该系统使用模板来存储有关类的元数据,这可能会影响这个问题中固有的一些假设。
我正在使用一个模板注册系统,该系统部分基于此处找到的答案:有没有办法从包含其类名的字符串中实例化对象?. 宏在我的系统中是不行的,就像使用 boost(或者实际上是任何第三方 API)一样。
问题:我是否可以根据输入类型是抽象还是具体来创建行为不同的模板?
我正在寻找这样的东西(此处使用的代码直接从链接问题中接受的答案复制而来):
struct BaseFactory {
typedef std::map<std::string, Base*(*)()> map_type;
static Base * createInstance(std::string const& s) {
map_type::iterator it = getMap()->find(s);
if(it == getMap()->end())
return 0;
return it->second();
}
protected:
static map_type * getMap() {
// never delete'ed. (exist until program termination)
// because we can't guarantee correct destruction order
if(!map) { map = new map_type; }
return map;
}
private:
static map_type * map;
};
template<typename T>
struct DerivedRegister : BaseFactory {
DerivedRegister(std::string const& s) {
getMap()->insert(std::make_pair(s, &createT<T>));
}
};
// in derivedb.hpp
class DerivedB {
...;
private:
static DerivedRegister<DerivedB> reg;
};
// in derivedb.cpp:
DerivedRegister<DerivedB> DerivedB::reg("DerivedB");
除了我希望 DerivedRegister 根据 T 是抽象还是具体的不同而表现不同。在 T 是抽象的情况下,我希望 DerivedRegister 不会在映射中注册类型。
正如我在背景中提到的,我已经继承了一个已经存在于类层次结构(抽象或具体)上的现有系统。修改这个现有系统以添加地图注册是微不足道的;但是,抽象类会引起问题,因为对它们调用 new 是无效的。
在 BaseFactory 和 DerivedRegister 之间添加额外的继承和模板层不会有问题;但是,DerivedRegister 已经存在于每个班级中,我无法更改。
我认识到我可以添加一个独立于现有模板类的唯一注册系统,并且只将它添加到具体类中。我特别询问是否有一种解决方案可以在不使用第三方库的情况下在 C++11 中避免这种情况(我知道很多限制......)。
解决方案
如果 T 是一个抽象类(即声明或继承至少一个纯虚函数的非联合类),则提供等于 的成员常量值
true
。对于任何其他类型,值为false
。
推荐阅读
- python - python - 如何计算一个单词在Python中特定类别的列中重复的次数?
- javascript - Node.JS 中的哨兵 - 无法读取未定义的属性 captureException
- java - 我应该使用什么中间方法在流调用中的某个点执行某些操作?
- javascript - React Native如何在项目目录中将对象写入文件(JSON)以进行调试
- google-chrome-extension - 有我自己的 chrome:// 或 file:// 指向不同的地方
- python - 空路径与其中任何一个都不匹配。姜戈
- python - 我如何让标题适合他们的单元格
- typescript - 使用“in”时出现“不能分配给 never 类型的参数”错误
- asynchronous - 如何在非异步代码上锁定()。等待 futures::lock::Mutex
- r - 将值范围拆分为相同数量的 bin