是否有可能以 ANY 方式在 C ++ 11/14 中使用类型(def)s的向量?
我尝试的第一件事就是有一个基类的向量,并以某种方式从它的派生形式中获取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 */ );
答案 0 :(得分:3)
也许您可以查看Loki的类型列表(请参阅here)。有一个问题是使用它们here。我认为这与你正在寻找的东西一样接近。 Boost MPL也有类似的东西(见this question),type lists和type vectors。
答案 1 :(得分:3)
Boost MPL为此提供了编译时构造,例如:
typedef boost::mpl::vector<int, double, std::string, CustomA, CustomB> seq_of_types;
您可以使用mpl中定义的大量元函数在编译类型中与此进行交互。还有一些运行时交叉功能。这里重要的一点是,这是类型的序列,没有每种类型的实例可以与之交互。甚至运行时函数也只允许与类型进行交互。
在此处提升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
的类型之一。然后在迭代时,您可以使用静态访问者对特定实例进行操作。我想我刚刚回答了一个问题,证明了这一点。
那会是哪个?
编辑:基于你的最后一条评论,然后后者(变体)并没有真正飞行,也没有普通继承。我认为融合矢量确实不是必需的,因为你不需要每种类型的实例。那么最合适的是mpl::vector
,并使用运行时函数mpl::for_each
答案 2 :(得分:2)
不,你不能。 C ++中的类型不是对象,也不能用作值。
根据您的实际需要,您可以使用type_info
(或者更确切地说,指向它们)来执行某些操作。这不是类型,它不能用于访问类型,但它可以用于例如相等比较,以确定两个type_info
对象是否引用相同或不同的类型。
答案 3 :(得分:0)
取决于你所说的“vector”
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正式化(但没有发明)“索引序列”的概念,它可以让你做几乎任意的元组类型 - &gt;元组类型转换。