4

是否有可能以任何方式在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 */ );
4

4 回答 4

4

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"};

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

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

或者,如果您使用可变参数类型(例如,则无需使用继承),同样是可能的,boost::variant例如:

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

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

那么会是哪一个呢?

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

于 2013-10-23T11:23:17.067 回答
3

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

于 2013-10-23T11:06:20.927 回答
2

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

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

于 2013-10-23T10:49:50.267 回答
0

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

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 形式化(但没有发明)“索引序列”的概念,它让您可以进行几乎任意的元组类型 -> 元组类型转换。

于 2013-10-28T19:53:04.820 回答