繁体   English   中英

如何使用c ++中的映射实现模板的返回类型查找?

[英]How do I implement return type lookup for templates using a map in c++?

我有两个数组。 一个包含指向基类的指针。 另一个包含一个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)

您可以为每种类型创建一个id,而不是枚举。

让我们具有模板的类型定义此id 由于您更喜欢constexpr,因此不能选择RTTI。 这是我想要一个类型ID时的工作:

template<typename>
void type_id() {}

using type_id_t = void(*)();

这很简单。 每个instanciated函数都将使用不同的地址,并且对于as if规则下的给定类型,函数的地址将始终相同。

然后,添加元数据非常简单。 我们可以像这样定义你的插件数组:

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实现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填充其他值。

将枚举(或整数)映射到类型的核心要素是某些东西的完全特化。 例如,你可以拥有

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM