【问题标题】:Does C++ have some analog of C# Type thing to store Types of classes in list / array?C++ 是否有一些类似于 C# Type 的东西来将类的类型存储在列表/数组中?
【发布时间】:2012-03-05 23:54:03
【问题描述】:

在 C# 中,我可以创建这样的 List 来存储类类型:

List<Type> types_list = new List<Type>();
types_list.add(typeof(int));
types_list.add(typeof(Process)); //and etc

我可以在 C++ 中做同样的事情吗?

【问题讨论】:

  • 取决于您以后要如何处理这些类型。在 C++ 中,您有 typeid 运算符,它返回 type_info 结构。所以,你可以拥有std::vector&lt;type_info&gt; v; v.push_back(type_id(Process)); etc.,但你以后对这些类型几乎无能为力
  • 以后可以根据 type_info 创建它所描述的类的实例吗?在 C# 中:Activator.CreateInstance(typeof(Process));
  • 我知道你正在尝试做这样的事情 :) 不,答案是否定的,你不能用type_info 来做。这需要大量的元编程,例如boost::mpl,但我无法详细说明
  • 那太糟糕了!这破坏了我所有的计划。但是感谢您的帮助!
  • 不要在代码中加入 html 格式,只需将其缩进 4 个空格,或者选择它并点击{} 按钮。

标签: c# c++ class types typeof


【解决方案1】:

也可以动态创建实例。鼓舞人心但不完整的代码:

class TypeProxy {
public:
    virtual ~TypeProxy() = default;

    char* create_default() const { return this->create_default_impl(); }

    template <typename T>
    static scoped_ptr<TypeProxy> CreateProxy ();

private:
    virtual void* create_default_impl() const = 0;
};


// A creator class.
template <typename T>
class Concrete : public TypeProxy {
    void *create_default_impl() const {
        return new T ();
    }
};


// Method to create creator proxies.
template <typename T>
scoped_ptr<TypeProxy> TypeProxy::CreateProxy () {
    return scoped_ptr<TypeProxy> (new Concrete<T>());
}

请注意,这只是一些未经测试的临时代码,用于显示操作模式。是否使用scoped_ptr值得商榷。

你可以使用可变参数模板来获得更多的花哨(参见例如 C++11 中的emplace[_(front|back)] 函数),但是由于不允许使用虚函数模板,它会变得复杂,但无论如何你还是必须传递参数列表。

(旁注:boost::shared_ptr 使用类似的虚拟/模板组合,这就是为什么您可以使用非多态基类和自定义删除器)

【讨论】:

  • 这很有趣!谢谢你展示它。在玩完 boost:mpl 之后,我应该更多地研究一下
【解决方案2】:

您可以使用boost MPL 存储类型列表。 示例:

#include <boost mpl stuff>

int main()
{
   typedef boost::mpl::vector<char, int> types;
   typedef boost::mpl::push_back<types, Process>::type newTypes;
   boost::mpl::at_c<newTypes, 2>::type objectOfTypeProcess;

}

除非你知道你在做什么,否则你真的不应该使用这个库,所以我的例子不是那么具体。无论如何,您可能需要花一些时间来习惯 mpl。

【讨论】:

  • 我认为这是我唯一的方法:P 感谢您的解决方案!
  • 尽管这提供了一种方法,但 OP 必须了解 C++ 是与 C# 完全不同的语言,具有不同的限制和目标。 Boost::mpl 在编译时做一些事情,所以如果人们希望在运行时读入一个文件并构造一个类型列表,他们就会失望。
  • @AlexanderKondratskiy:我试图警告......但是,OP 决心这样做......
【解决方案3】:

参见typeidtype_info

请注意,您不能使用 type_info 类创建它所代表的类型的新实例,因为 C++ 不支持。

【讨论】:

  • 我不太确定你不能用 C++ 做到这一点。我的意思是,你知道boost mpl 这么好,坚持认为这是不可能的吗?
  • 你应该可以做类似if(t==typeid(Foo)) { Foo x; do something with x; }
  • @ArmenTsirunyan 我坚持我的说法,typeidtype_info 不能用于创建新实例。虽然现在只看 Boost.mpl,但它似乎使用模板来创建可用于创建实例的 typedef。但这都是编译时的魔法,而不是运行时的魔法。
猜你喜欢
  • 2011-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-23
相关资源
最近更新 更多