【问题标题】:Vector of typedefstypedef 向量
【发布时间】:2013-10-29 03:53:04
【问题描述】:

是否有可能以 ANY 方式在 C++11/14 中拥有类型(def)的向量?

我尝试的第一件事是拥有一个基类的向量,并以某种方式从它的派生形式中获取 typedef,但无论我尝试什么都无法让它工作(最不可能)。

伪 C++:

class base
{
   /* somehow access 'type' from derived */
}

template <typename T>
class derived : base
{
   typedef T type;
}

vector<base*> vec;
vec.push_back( new derived<int> );
vec.push_back( new derived<double> );
vec.push_back( new derived<float> );
vec.push_back( new derived<string> );

for(auto& item : vec)
   static_cast< item->type >( /* something */ );

【问题讨论】:

  • 不,听起来你需要一个智能指针向量或引用包装器(我会推荐这两者中的前者)。但是您仍然需要知道派生类型才能请求它。
  • 您到底想完成什么?我可以毫无问题地做class SomeClass; typedef SomeClass X; std::vector&lt;X&gt; v;
  • 您是否正在寻找类似Boost.MPLBoost.Fusion 的东西?
  • @rwols:这不是我想要的。我需要的是有一个引用不同类型的 typedef 向量。
  • 你可以写using my_types = std::tuple&lt;T1, T2, T3&gt;。然后你可以用std::tuple_element索引它。

标签: c++ reflection c++14


【解决方案1】:

Boost MPL 为此提供了编译时构造,例如:

typedef boost::mpl::vector<int, double, std::string, CustomA, CustomB> seq_of_types;

您可以使用 mpl 中定义的大量元函数集在编译类型时与之交互。还有一些运行时交叉功能。这里重要的一点是,这是一个 types 的序列,没有每个类型的实例可以与之交互。甚至运行时函数也只允许与类型进行交互。

Boost Fusion(和std::tuple)在这里提供一个运行时异构容器,例如

boost::fusion::vector<int, double, std::string> v{10, 100., "Foo"};

现在在编译时,您可以访问每个条目的类型信息,并且在运行时,您可以使用序列中每种类型的实例。

有可能你试图实现的目标可以通过简单的继承来完成,而不必求助于上述方法,因此向量包含一个指向基类的指针,它有一个在派生类中被覆盖的虚函数哪个做你想要的。这可能是最干净的。

另外,如果您使用诸如boost::variant 之类的可变类型,则无需使用继承,例如:

std::vector<boost::variant<int, double, std::string>> entries;

现在每个条目都是intdoublestd::string 类型之一。然后在您迭代时,您可以使用静态访问者对特定实例进行操作。我想我刚才回答了一个关于 SO 的问题,这证明了这一点。

那会是哪一个呢?

编辑:根据您的最后一条评论,后者(变体)并没有真正发挥作用,普通继承也没有。我认为融合向量也不是必需的,因为您不需要每种类型的实例。那么最适合你的是mpl::vector,并使用运行时函数mpl::for_each

【讨论】:

    【解决方案2】:

    也许您可以查看 Loki 的类型列表(请参阅 here)。有一个关于使用它们的问题here。我认为这与您正在寻找的东西一样接近。 Boost MPL 也有类似的东西(见this question),有type liststype vectors

    【讨论】:

      【解决方案3】:

      不,你不能。 C++ 中的类型不是对象,它们不能用作值。

      根据您的实际需要,您可以使用type_info(或者更确切地说,指向它们的指针)来做一些事情。这不是类型,也不能用于访问类型,但它可以用于例如相等比较以确定两个 type_info 对象是指相同的类型还是不同的类型。

      【讨论】:

        【解决方案4】:

        取决于你所说的“矢量”是什么意思

        std::tuple 的特化是(编译时)有序的类型集合。 您可以索引它们(未经测试的代码):

         typedef std::tuple<int, long, void, std::string, std::complex<float> Tuple;
         typename std::tuple_element<1, Tuple>::type foo; // foo is of type long
        

        您可以对元组进行各种操作(在编译时),这些操作的结果就是类型(或其他元组)。 C++14 形式化了(但没有发明)“索引序列”的概念,它可以让您进行几乎任意的元组类型 -> 元组类型转换。

        【讨论】:

          猜你喜欢
          • 2012-10-10
          • 2012-08-31
          • 2017-08-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-06-19
          • 2013-05-25
          相关资源
          最近更新 更多