【问题标题】:Value to type runtime mapping值类型运行时映射
【发布时间】:2016-08-20 17:56:45
【问题描述】:

考虑这段代码

enum Types
{
    t1,
    t2
};

struct Base 
{
    Types typeTag;
    Base(Types t) : typeTag(t){}
};

template<typename T>
struct Derived : Base 
{
    using Base::Base;
    T makeT() { return T(); }
};

int main() 
{
    Base *b = new Derived<std::string>(t1);
    auto d = getDerivedByTag(b); // How ??
    d->makeT();
    return 0;
}

是否可以在运行时通过 Base::typeTag 值恢复派生类型参数?显然,需要一些外部预先准备好的映射,但我无法弄清楚确切的方法。

【问题讨论】:

    标签: c++ templates inheritance


    【解决方案1】:

    你想要的基本上是一个reflection,它在 C++ 中(尚不)支持。有一些方法可以模拟它或解决它,但它们通常很冗长且不优雅。我建议重新考虑您的设计,尤其是您对auto 的使用。正如您的代码所暗示的那样,它不应该替代“任何类型”。当实际类型很长或被混淆(通常发生在模板中)、嵌套等时,它意味着代码的简化。当您不知道类型时不是这样!因为那样你就不能真正使用它,不是吗。

    因此,您必须以一种或另一种方式直接检查typeTag 并根据该信息继续。或者,您需要直接使用Base 使用多态性(调用传播到Derived 的虚拟方法)。对于类型联合,您可以使用 boost::variant(如果您不关心 Derived 模板参数是什么类型)或其他一些框架/库替代方案,例如 Qt 中的 QVariant

    【讨论】:

      【解决方案2】:

      我不确定我的理解是否正确。

      #include "iostream"
      enum Types
      {
          t1,
          t2
      };
      
      template<typename T>
      struct Base 
      {
          typedef T DerivedType;
          Types typeTag;
          Base(Types t) : typeTag(t){}
          DerivedType* operator()() {
            return static_cast<DerivedType*>(this);
          }
      };
      
      template<typename T>
      struct Derived : Base<Derived<T>>
      {
          Derived(Types t): Base<Derived<T>>(t) {}
          T makeT() { return T(); }
      };
      
      int main() 
      {
          Base<Derived<std::string>> *b = new Derived<std::string>(t1);
          auto d = (*b)();
          d->makeT();
          return 0;
      }
      

      https://godbolt.org/g/uBsFD8

      我的实现与 typeTag 无关。

      你的意思是getDerivedByTag(b-&gt;typeTag)而不是getDerivedByTag(b)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-07-21
        • 2017-08-08
        • 2015-03-22
        • 1970-01-01
        • 1970-01-01
        • 2019-01-22
        • 1970-01-01
        相关资源
        最近更新 更多