切换取决于对象类型

switch depending on object type

本文关键字:类型 对象 取决于      更新时间:2023-10-16

我想知道是否有一种更好的方式(更易于阅读,更少的冗长)。

我有具有混凝土Foo实现类型的对象foo,可以将其称为foo1 .. foon。

我还具有FOO的描述的字符串表,例如foo1" bars the foo1"。我想做的是某种类型检查,具体取决于FOO的实际类型。目前我要做:

std::string fooUtils::translate(Foo * foo){
   if(typeid(foo) == typeid(Foo1){
      return "bars the Foo1";
   }
   else if
     ...
}

我想知道是否有更好的方法。

我想到的第一个是存储std :: map<STD :: TypeInfo,STD :: String> - 这是我热衷于寻求的解决方案,但我不知道将类型信息作为地图的钥匙的任何副作用(是否有?)。我还想知道是否有什么可以以较少的详细方式比较类型的东西,例如boost :: is_type<foo1,foo>或类似的东西。

这就是virtual成员函数的目的:

std::string fooUtils::translate(Foo * foo) {
    foo->translate();
}

with:

struct Foo {
    virtual std::string translate() const { return "base"; }
};
struct Foo1 : Foo {
    std::string translate() const override {
        return "bars the Foo1";
    }
};

这是type_info搜索实用程序:

template<class T, class...Ts>
std::array<std::decay_t<T>, sizeof...(Ts)+1> make_array( T&& t, Ts&&...ts ) {
  return {{ std::forward<T>(t), std::forward<Ts>(ts)... }};
}
template<class F, class T, size_t N>
std::array<T, N> sorted( std::array<T, N> arr ) {
  std::sort( begin(arr), end(arr), F{} );
  return arr;
}
struct p_type_info_sort {
  bool operator()( std::type_info const* lhs, std::type_info const* rhs ) const {
    return lhs->before(*rhs);
  }
};
template<class...Ts, class T>
std::type_info const* which(T const& t) {
  static const auto table=sorted<p_type_info_sort>(make_array(
    (&typeid(Ts))...
  ));
  auto r = std::equal_range( begin(table), end(table), &typeid(t), p_type_info_sort{} );
  if (r.first==r.second) return nullptr;
  return *r.first;
}

您执行which<A, B, C, D>(*a),然后返回类型 *a的类型列表中的哪一项完全匹配(动态)。它通过返回type_info const*来做到这一点,如果找不到匹配项,则可以通过nullptr来做到这一点。

现在这通常是一个坏主意。以上仅具有确切的匹配。通常,如果您有那么多的多态性,则需要将其放入界面中,并且失败了,您可能会有其他一些设计缺陷。

实时示例

在此线程中,您可以找到type2enum转换和向后的enum2Type转换:如何进行键入参数包类?

答案的提取:

template<class T> type2enum();
#define TYPE2ENUM_SPEC(TYPE, ENUM) 
template<> type2enum<TYPE>() 
{ return ENUM; }
enum { T1enum, T2enum, T3enum }
TYPE2ENUM_SPEC(type1_t, T1enum);
TYPE2ENUM_SPEC(type2_t, T2enum);
TYPE2ENUM_SPEC(some_third_type_t, T3enum);