如何在c++中使用映射实现模板的返回类型查找
How do I implement return type lookup for templates using a map in c++?
我有两个数组。一种包含指向基类的指针。另一个包含Enum,其值给出指向实类型的指针。
我现在想有一个函数,可以为我获得一个数组,其中包含与它们相关联的特定Enum值的条目,并返回具有正确返回类型的该数组。
示例(半伪代码):std::array<BaseType, 2> a = { TypeAInstance, TypeBInstance };
std::array<TypeEnum, 2> b = { TypeA, TypeB };
template<typename SearchType>
std::array<SearchType*, 2> GetEntriesOfType()
{
std::array<SearchType*, 2> ret;
for(int i = 0; i < 2; i++)
{
ret[i] = nullptr;
if(b[i] == EnumForType(SearchType)) ret[i] = a[i];
}
}
然而,我不知道如何构造EnumForType函数或反向TypeForEnum函数,这将允许我使用
声明模板返回类型:template<SearchTypeEnum>
TypeForEnum(SearchTypeEnum) GetEntriesOfType();
如果可能的话,我想定义这样一个constexpr函数。潜在的问题是,我有一个数组的插件,我迭代。每个插件需要根据类型进行不同的处理。然而,由于类型是运行时依赖的,我不能有动态分配(嵌入式系统约束),我存储所有的插件在一个固定的保留内存空间。我需要在运行时以某种方式将指向基类的指针强制转换为正确的类型,并相应地处理它。
这个GetEntriesOfType函数应该使这更方便。当然,我可以获取两个数组,然后在两个数组上进行迭代时执行switch语句,但我希望将其简化为该库的最终用户。
一种方法是将每个类类型映射到枚举数值:
class A;
class B;
enum class Types {
A,
B
};
template<class T> struct EnumForType;
template<> struct EnumForType<A> { static constexpr Types value = Types::A; };
template<> struct EnumForType<B> { static constexpr Types value = Types::B; };
int main() {
auto a = EnumForType<A>::value;
auto b = EnumForType<B>::value;
}
你可以这样使用:
if(b[i] == EnumForType<SearchType>::value)
将枚举(或整数)映射到类型的核心要素是某种东西的完全专门化。例如,您可以使用
template <TypeEnum> struct EnumToType;
template <> struct EnumToType<TypeA> { using type = TypeAType; };
template <> struct EnumToType<TypeB> { using type = TypeBType; };
// ...
…然后在你的函数中适当地使用它,例如(这假设BaseType
实际上是一个指针类型;如果不是,则在创建数组时将值切片,并且无法移植地恢复具体类型):
std::array<BaseType, 2> a = { TypeAInstance, TypeBInstance };
std::array<TypeEnum, 2> b = { TypeA, TypeB };
template<SearchTypeEnum E>
std::array<typename EnumToType<E>::type*, 2> GetEntriesOfType() {
std::array<typename EnumToType<E>::type*, 2> rc;
for (int i = 0; i != 2; ++i) {
rc[i] = a[i] == E? static_cast<typename EnumToType<E>::type*>(b[i]);
}
return rc;
}
您可以为每种类型创建一个id,而不是enum。
让我们用模板为类型定义这个id。因为您更喜欢constexpr,所以RTTI不是一个选项。当我想要一个类型id时,我要这样做:
template<typename>
void type_id() {}
using type_id_t = void(*)();
就是这么简单。每个实例化的函数都有一个不同的地址,并且在规则下,函数的地址对于给定类型总是相同的。
那么,添加元数据就很容易了。我们可以这样定义你的插件数组:
std::array<std::pair<type_id_t, BaseType*>, 2> a = {
std::make_pair(type_id<TypeA>, typeAInstance),
std::make_pair(type_id<TypeB>, typeBInstance)
};
在这里,您只是将实例与标识类型的值关联起来。您的GetEntriesOfType
变得微不足道的实现:
template<typename SearchType>
std::array<SearchType*, 2> GetEntriesOfType() {
std::array<SearchType*, 2> ret;
for(int i = 0; i < 2; i++) {
ret[i] = nullptr;
if(a[i].first == &type_id<SearchType>) ret[i] = a[i].second;
}
}
我通常避免将类型与枚举相关联,因为枚举并不表示类型,而是映射到简单的整数值。
另外,如果你的数组是constexpr,你甚至可以返回一个数组,只有合适的大小来适应SearchType
的所有实例,而不是用nullptr
填充其他值。
- 查找表究竟是如何工作的,以及如何实现它们
- 为什么我的 Rcpp 实现查找唯一项的数量比基本 R 慢?
- pacman 实现 BFS 来查找 pacman 路径
- 如何实现 std::map::查找包含两个结构'Pos'结构的比较逻辑,每个结构包含 x 和 y 坐标
- 查找矩阵实现的 [] 运算符中的设计缺陷
- 在哪里查找 GCC 实现定义行为的实现?
- 在我的图实现中查找边的数量并执行拓扑排序
- 在使用无序多映射实现的有向图中查找循环
- 如何在将多维 int 数组映射到 C++ 中的字符串时实现在地图上查找或计数
- 实现用于查找路径的递归函数时出现问题
- 分段错误(核心转储)实现联合查找C++
- C++中无向图算法中查找周期的实现.
- 查找使用AgentX实现SNMP表的示例代码
- matlab在opencv中查找函数的实现
- 如何查找编译器实现细节
- 如何在c++中使用映射实现模板的返回类型查找
- 查找最近的点对-如何在递归侧对函数调用中实现拆分对
- Constexpr查找实现
- 为什么不为' at '和' operator[] '实现异构比较查找
- 给定一个按行排序的整数矩阵结构,如何实现二分查找?