我看到了这个漂亮的图形,它根据不同的数据要求对哪个STL容器进行分类,例如:
- 固定尺寸与可变尺寸
- 相同的数据Vs不同类型
- 排序Vs未排序数据
- 顺序V随机访问
http://plasmahh.projectiwear.org/cce_clean.svg
我注意到在那张图片中,C ++ STL没有容器
C ++不具备此功能吗?
PS - 容器的不同属性可以有许多排列,STL也可能没有提供许多其他属性。
答案 0 :(得分:17)
通常,C ++容器设计用于使用模板保存单个类型的对象。如果你想要从一种类型派生的不同类型,你可以存储一个指针容器(我猜你也可以有任何容器的void *),例如的std ::矢量< MyBaseType * GT;
如果你想要完全不相关的类型,你可以存储可以安全地引用其他类型的对象,例如boost :: any。
http://www.boost.org/doc/libs/1_47_0/doc/html/any.html
提升网站的一些例子:
#include <list>
#include <boost/any.hpp>
using boost::any_cast;
typedef std::list<boost::any> many;
void append_int(many & values, int value)
{
boost::any to_append = value;
values.push_back(to_append);
}
void append_string(many & values, const std::string & value)
{
values.push_back(value);
}
bool is_int(const boost::any & operand)
{
return operand.type() == typeid(int);
}
bool is_char_ptr(const boost::any & operand)
{
try
{
any_cast<const char *>(operand);
return true;
}
catch(const boost::bad_any_cast &)
{
return false;
}
}
boost :: variant类似,但您指定了所有允许的类型,而不是允许容器中的任何类型。
http://www.boost.org/doc/libs/1_47_0/doc/html/variant.html
std::vector< boost::variant<unsigned, std::string> > vec;
vec.push_back( 44);
vec.push_back( "str" );
vec.push_back( SomthingElse(55, 65) ); //not allowed
答案 1 :(得分:10)
标准库中的基本原则是“容器”是同质的; C ++标准不认为std::pair
或std::tuple
之类的东西是容器。 (我认为图表具有误导性,因为它确实将它们视为容器。)如果您需要异构容器,则必须使用boost::variant
的容器,或者沿着这些行的东西。
答案 2 :(得分:4)
std::pair
和std::tuple
几乎不是C ++容器....所以不,STL中没有异构容器,因为没有必要让它们内置。< / p>
有几种方法可以创建这样的容器。我建议的方法是:
对于多态性,您可以检查Boost Pointer Container库。
boost::ptr_vector<Base> vec;
vec.push_back(new Derived);
vec.push_back(new Derived2);
它模仿STL容器,但提供了面向多态的功能:
Base&
new_clone
方法)boost::ptr_vector<Base>::iterator it;
,*it
为Base&
如果您的类型不相关,则另一种可能是使用Boost Variant。基本上,变体类似于:
enum { Type1, Type2, ... } _type;
union {
SomeType1 _1;
SomeType2 _2;
...
} _u;
当然,由于它的提升,它提供了特定的保证,以确保您只能访问当前活动的联合的成员,并解除对类的限制,其中构造函数/析构函数不能在传统中使用联合。
它还提供了static_visitor
等设施,它等同于类型上的开关,如果没有访问其中一个可能的状态,它将使编译错误。
答案 3 :(得分:2)
固定大小的异构容器(如std::tuple
)要求在编译时知道类型。如果要创建可变大小的异构容器,只需创建std::vector<std::tuple<T1,T2,...,TN>>
。
如果你想要一个异构容器,其中的类型在编译时是未知的(无论是变量还是固定大小),你必须将指针(或智能指针)存储到编译时已知的基类型,或者或者考虑类似boost::any
的容器。 STL不直接提供固定或可变大小的容器,其中运行时确定异构元素。
答案 4 :(得分:1)
如果您存储的元素是boost::any
或boost::variant
,那么您可以间接存储异构数据。
答案 5 :(得分:0)
我会指出您这个图书馆。实现为真正的异构容器 https://github.com/hosseinmoein/DataFrame 它不使用多态性,因此存储指针。它像std :: vector一样使用连续的内存存储。
您可以编写这样的代码
typedef StdDataFrame<unsigned long> MyDataFrame;
MyDataFrame df;
std::vector<int> intvec = { 1, 2, 3, 4, 5 };
std::vector<double> dblvec = { 1.2345, 2.2345, 3.2345, 4.2345, 5.2345 };
std::vector<double> dblvec2 = { 0.998, 0.3456, 0.056, 0.15678, 0.00345,
0.923, 0.06743, 0.1 };
std::vector<std::string> strvec = { "Insight", "John Dow", "Alakazam",
"Persian Prince", "Bugs Bunny" };
std::vector<unsigned long> ulgvec = { 1UL, 2UL, 3UL, 4UL, 5UL, 8UL, 7UL, 6UL }
std::vector<unsigned long> xulgvec = ulgvec;
// This is only one way of loading data into a DataFrame instance. There are
// many different ways of doing it. Please see the documentation,
// or dataframe_tester.cc
int rc = df.load_data(std::move(ulgvec), // Index column
std::make_pair("int_col", intvec),
std::make_pair("dbl_col", dblvec),
std::make_pair("dbl_col_2", dblvec2),
std::make_pair("str_col", strvec),
std::make_pair("ul_col", xulgvec));