将模板参数解析为其序数索引

时间:2014-12-18 23:21:20

标签: c++ templates

标题描述了我的问题的核心,虽然实际问题很难描述。

本质上,我需要创建一个类似于std :: tuple的类,它也允许用户按类型而不是索引访问其成员(假设类型唯一性得到保证),但我不希望类本身是模板化,即只有构造函数。

例如,如果我的班级被命名为" Foo",我想做以下事情,

Foo foo { &A, &B, &C };  // where A, B, C are of unique types

然后能够通过以下方式检索指针:

foo.Get<TypeA>(); // should return &A
foo.Get<TypeB>(); // should return &B

并保留Foo的类声明而不使用模板。

1 个答案:

答案 0 :(得分:2)

我认为将Foo用作类的唯一方法是RTTI。这些方面的东西:

#include <iostream>
#include <map>
#include <string>
#include <typeindex>

class Foo {
public:
  template<typename... Args>
  Foo(Args*... args) {
    // bit hackish here, but this way we can use pack expansion
    // to populate the map.
    void *foo[] = {
      (data_[std::type_index(typeid(Args))] = static_cast<void*>(args))...
    };
  };

  template<typename T> T *GetData() const {
    auto iter = data_.find(std::type_index(typeid(T)));

    if(iter == data_.end()) {
      return nullptr;
    }

    return static_cast<T*>(iter->second);
  }

private:
  typedef std::map<std::type_index, void*> storage;
  storage data_;
};

int main() {
  std::string s = "foobar";
  int i = 2;
  double d = 3.0;

  Foo f(&i, &d, &s);

  std::cout << *f.GetData<int        >() << "\n"
            << *f.GetData<double     >() << "\n"
            << *f.GetData<std::string>() << "\n";
}