C++ 中的异构容器
我看到了这个漂亮的图形,它根据数据的不同要求对适合哪个 STL 容器进行了分类,例如:
-- 固定大小 Vs 可变大小
-- 相同类型的数据 Vs 不同类型
-- 排序数据与未排序数据
-- 顺序访问与随机访问
< a href="http://plasmahh.projectiwear.org/cce_clean.svg" rel="noreferrer">http://plasmahh.projectiwear.org/cce_clean.svg
我注意到那个图像,C++ STL 没有
- 可变大小
- 异构的容器(不同类型的数据)。
C++ 没有这方面的东西吗?
PS - 容器的不同属性可能有多种排列,而 STL 中也可能未提供许多其他排列。
I saw this nice graphic which classifies which STL container would suit based on different requirements of data such as:
-- Fixed Size Vs Variable size
-- Data of same tyme Vs different type
-- Sorted Vs unsorted data
-- Sequential Vs random access
http://plasmahh.projectiwear.org/cce_clean.svg
I notice in that image, that C++ STL there is no container which is
- Variable Size
- Heterogenous (data of different types).
Doesn't C++ have something for this?
PS - There can be many permutations made out the different properties of the containers and many others too might not be provided in STL.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
一般来说,C++ 容器被设计为使用模板保存单一类型的对象。如果您想要从一种类型派生的不同类型,您可以存储一个指针容器(我猜您也可以有一个 void* 到任何东西的容器...),例如 std::vector。
如果您想要完全不相关的类型,您可以存储可以安全引用其他类型的对象,例如 boost::any。
http://www.boost.org/doc/libs/1_47_0 /doc/html/any.html
boost 站点上的一些示例:
boost::variant 类似,但您指定所有允许的类型,而不是允许容器中的任何类型。
http://www.boost.org/doc/libs/1_47_0 /doc/html/variant.html
Well generally C++ Containers are designed to hold objects of a single type using templates. If you want different types that are all derived from one type you can store a container of pointers (I guess you could also have a container of void* to anything...) e.g. std::vector<MyBaseType*>.
If you want completely unrelated types, you can store objects that can safely reference those other types, such as boost::any.
http://www.boost.org/doc/libs/1_47_0/doc/html/any.html
Some examples off the boost site:
boost::variant is similar, but you specify all the allowed types, rather than allowing any type in your container.
http://www.boost.org/doc/libs/1_47_0/doc/html/variant.html
标准库的基本原则是“容器”是同质的; C++ 标准不认为
std::pair
或std::tuple
之类的东西是容器。 (我认为该图具有误导性,因为它确实将它们视为容器。)如果您需要异构容器,则必须使用boost::variant
容器,或类似的容器线。The basic principle in the standard library is that "containers" are homogeneous; the C++ standard doesn't consider things like
std::pair
orstd::tuple
to be containers. (I'd consider the graph misleading, since it does consider them as containers.) If you need a heterogeneous container, you'd have to use a container ofboost::variant
, or something along those lines.尚未被 Boost 接受的库。但提议纳入的目标是:
http://rawgit。 com/joaquintides/poly_collection/website/doc/html/index.html
它提供了一个名为any_collection的好类,它允许通过 boost::type_erasure::any 拥有异构容器:
http://rawgit.com/joaquintides/poly_collection/website/doc/html/poly_collection/tutorial.html#poly_collection.tutorial.basics.boost_any_collection
否则在 C++17 中有简单的实现方法:
https://gieseanw.wordpress.com/ 2017/05/03/a-true-heterogeneous-container-in-c/
引用上述文章的例子:
然后很容易使用:
作者声明这是一个玩具实现,但我认为这是一种非常聪明的实现方式,并且比 poly_collection 或变体向量具有简单性优势。
A library which is not yet accepted into Boost. But which was proposed for inclusion is targeted toward this :
http://rawgit.com/joaquintides/poly_collection/website/doc/html/index.html
It provides a nice class named any_collection which allows one to have an heterogeneous container via boost::type_erasure::any :
http://rawgit.com/joaquintides/poly_collection/website/doc/html/poly_collection/tutorial.html#poly_collection.tutorial.basics.boost_any_collection
Otherwise in C++17 there are simple way to implement this :
https://gieseanw.wordpress.com/2017/05/03/a-true-heterogeneous-container-in-c/
Quoting the example of the aforementioned article :
Then usable easily :
The author states it's a toy implementation, but I think this is a really clever way to implement it, and has a simplicity advantage over poly_collection or a vector of variants.
std::pair
和std::tuple
几乎不是 C++ 容器......所以不,STL 中没有异构容器,因为没有必要拥有它们内置。有多种方法可以创建此类容器。我推荐的方法是:
对于多态,您可以检查 Boost Pointer Container 库。
它模仿 STL 容器,但提供面向多态性的功能:
Base&
new_clone
方法)boost::ptr_vector ::iterator it;
,*it
是一个Base&
如果您的类型不相关,另一种可能性是使用 Boost 变体。基本上,一个变体类似于:
当然,由于它是 boost,它提供了特定的保证,以确保您只能访问当前活动的联合成员,并解除了对构造函数/析构函数不能在以下情况下使用的类的限制:传统工会。
它还提供了诸如
static_visitor
之类的功能,它相当于类型上的开关,并且如果未访问其中一种可能的状态,则会产生编译错误。std::pair
andstd::tuple
are hardly C++ containers.... so no, there is no heterogeneous containers in the STL, because it's not necessary to have them built-in.There are several approaches to create such containers. The approaches I would recommend are:
For Polymorphism, you can check Boost Pointer Container library.
It mimicks the STL containers, but provides functionalities geared toward polymorphism:
Base&
new_clone
methods)boost::ptr_vector<Base>::iterator it;
,*it
is aBase&
If your types are unrelated, the other possibility is to use Boost Variant. Basically, a variant is similar to:
Of course, since it's boost, it provides specific guarantees to make sure that you can only access the member of the union that is currently active and lifts the restriction on classes with constructors / destructors not being usable in traditional unions.
It also provides facilities, like the
static_visitor
, which is the equivalent of a switch on the type, and will make the compilation error out if one of the possible states is not visited.固定大小的异构容器(如 std::tuple )要求在编译时知道类型。如果您想创建一个可变大小的异构容器,只需创建一个 std::vector
std::tuple 即可。 std::tuple>
如果您想要一个异构容器,其中类型在编译时未知(无论是可变大小还是固定大小) 。必须存储指向编译时已知的基类型的指针(或智能指针),或者考虑类似boost::any 的容器。STL 不直接以固定或固定方式提供此类容器。大小可变,异构元素在运行时确定。
The fixed size heterogenous containers (like
std::tuple
require the types to be known at compile time. If you want to make a variable sized heterogeneous container, just make astd::vector<std::tuple<T1,T2,...,TN>>
.If you want a heterogeneous container where the types is not known at compile time (whether that would be variable or fixed sized) you'll have to store pointers (or smart pointers) to a base type known at compile time, or alternatively consider something like a container of
boost::any
. The STL doesn't directly provide such a container in either fixed or variable sized with heterogeneous elements determined at run time.如果您存储的元素是
boost::any
或boost::variant
那么你可以间接存储异构数据。If the element you store would be a
boost::any
orboost::variant
then you can indirectly store heterogeneous data.我会向您推荐这个图书馆。它被实现为真正的异构容器
https://github.com/hosseinmoein/DataFrame
它不使用多态性,因此存储指针。它使用连续的内存存储,就像 std::vector 一样。
你可以这样写代码
I would point you to this library. It is implemented to be true heterogeneous container
https://github.com/hosseinmoein/DataFrame
It does not use polymorphism and consequently store pointers. It uses continuous memory storage, just like a std::vector.
You can write code like this
注意到所有提到 boost::variant 的答案。
但从C++17开始,标准本身提供了
std::variant
。它是一个类型安全的联合。Noted all the answers mentioning about boost::variant.
But from C++17 the standard itself provides
std::variant
. It is a type-safe union.