是否可以以的任何方式在 C++ 11/14 中具有类型(def)的 vector ?

我尝试的第一件事是有一个基类的 vector ,并以某种方式从它的派生形式中获得了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 */ );

最佳答案

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

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

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

Boost Fusion(和std::tuple)进入此处以提供运行时异构容器,例如
boost::fusion::vector<int, double, std::string> v{10, 100., "Foo"};

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

您可能想要实现的目标可以通过简单的继承完成而不必求助于上面的方法,因此 vector 持有指向基类的指针,该基类具有一个虚函数,该虚函数在派生类中被覆盖,该类将执行以下操作:你要。这可能是最干净的。

另外,如果您使用可变参数类型(例如boost::variant),则无需借助继承即可实现相同的目的,例如:
std::vector<boost::variant<int, double, std::string>> entries;

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

那会是什么呢?

编辑:根据您的最后一条评论,然后后者(变体)不会真正实现,也不会进行纯继承。我认为融合 vector 确实不是必需的,因为您不需要每种类型的实例。然后,最适合您的是mpl::vector,并使用运行时函数 mpl::for_each

10-07 13:54
查看更多