如何创建进程间集装箱升压进程间矢量? [英] How to I create a boost interprocess vector of interprocess containers?

查看:104
本文介绍了如何创建进程间集装箱升压进程间矢量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我喜欢创造的含间容器类升压进程间向量。
下面code工作,直到调整大小功能调用,当然,因为我的班没有默认构造函数。
如何解决我这个问题?
该例子是基于升压<一href=\"http://www.boost.org/doc/libs/1_56_0/doc/html/interprocess/allocators_containers.html#interprocess.allocators_containers.containers_explained.containers_of_containers\"相对=nofollow>集装箱货柜例如

谢谢
马库斯

 的#include&LT;升压/间/ managed_shared_memory.hpp&GT;
#包括LT&;升压/间/分配器/ allocator.hpp&GT;
#包括LT&;升压/间/集装箱/ map.hpp&GT;
#包括LT&;升压/间/集装箱/ vector.hpp&GT;
#包括LT&;升压/间/集装箱/ string.hpp&GT;使用空间boost ::进程间;//分配器和容器的类型定义
的typedef managed_shared_memory :: segment_manager segment_manager_t;
typedef的分配器&LT;无效,segment_manager_t&GT; void_allocator;
typedef的分配器&LT; INT,segment_manager_t&GT; int_allocator;
typedef的矢量&lt;整型,int_allocator&GT; INT_VECTOR;
typedef的分配器&LT;焦炭,segment_manager_t&GT; char_allocator;
basic_string的typedef的LT&;焦炭,的std :: char_traits&LT;焦炭&gt;中char_allocator&GT; char_string;类complex_data
{
上市:
   INT ID_;
   char_string char_string_;
   INT_VECTOR int_vector_;   //由于void_allocator可以转换为任何其他分配器&LT;吨&gt;中我们可以简化
   //初始化服用只是一个分配器为所有内部容器。
   complex_data(常量void_allocator&安培; void_alloc)
      :ID _( - 1),char_string_(void_alloc),int_vector_(void_alloc)
   {}
   //其他成员...
};
typedef的分配器&LT; complex_data,segment_manager_t&GT; complex_data_allocator;
typedef的矢量&lt; complex_data,complex_data_allocator&GT; complex_data_vector;诠释的main()
{
   //删除建设和破坏共享内存
   结构shm_remove
   {
      shm_remove(){shared_memory_object ::删除(MySharedMemory); }
      〜shm_remove(){shared_memory_object ::删除(MySharedMemory); }
   }卸妆;   //创建共享内存
   managed_shared_memory段(create_only,MySharedMemory,65536);   //一个分配器转换为任何分配器&LT; T,segment_manager_t&GT;类型
   void_allocator alloc_inst(segment.get_segment_manager());   //构建共享内存映射并填写
   complex_data * complex_data0_ = segment.construct&LT; complex_data&GT; (MyCompexData)(alloc_inst);   complex_data0 _-&GT; char_string_ =你好沃尔德;
   complex_data0 _-&GT; int_vector_.push_back(3);   complex_data * complex_data1_ = segment.find_or_construct&LT; complex_data&GT; (MyCompexData)(alloc_inst);
   complex_data1 _-&GT; int_vector_.push_back(6);   性病::法院LT&;&LT; complex_data1 _-&GT;&ID_ LT;&LT; ,&所述;&下; complex_data0 _-&GT; char_string_;
   用于(为size_t我= 0; I&LT; complex_data1 _-&GT; int_vector_.size();我++)的std ::法院LT&;&LT; ,&所述;&下; complex_data1 _-&GT; int_vector_ [I]
   complex_data_vector * complex_data_vector0 = segment.construct&LT; complex_data_vector&GT; (MyCompexDataVector)(alloc_inst);   / **
    *问题
    *如何我调整或增加新的元素?
    ** /
   complex_data_vector0-&GT;调整(3);
   返回0;
}


解决方案

REWRITE

由于升压容器支持范围的分配模式,您可以只使用一个作用域的分配,并且容器会自动把它传递新元素的内部结构(或安放),当元素具有 uses_allocator&LT ;&GT; 特点为它专门肯定:

<大骨节病> 住在Coliru

 的#include&LT;升压/间/ managed_shared_memory.hpp&GT;
#包括LT&;升压/集装箱/ scoped_allocator.hpp&GT;
#包括LT&;升压/间/分配器/ allocator.hpp&GT;
#包括LT&;升压/间/集装箱/ map.hpp&GT;
#包括LT&;升压/间/集装箱/ vector.hpp&GT;
#包括LT&;升压/间/集装箱/ string.hpp&GT;使用空间boost ::进程间;//分配器和容器的类型定义
的typedef managed_shared_memory :: segment_manager segment_manager_t;
TYPEDEF提振::容器:: scoped_allocator_adaptor&LT;分配器&LT;无效,segment_manager_t&GT; &GT;
                                                                     void_allocator;
的typedef void_allocator ::重新绑定&LT; INT&GT; ::其他int_allocator;
typedef的矢量&lt;整型,int_allocator&GT; INT_VECTOR;的typedef void_allocator ::重新绑定&LT;焦炭&gt;其他:: char_allocator;
basic_string的typedef的LT&;焦炭,的std :: char_traits&LT;焦炭&gt;中char_allocator&GT; char_string;类complex_data
{
上市:
   INT ID_;
   char_string char_string_;
   INT_VECTOR int_vector_;   //由于void_allocator可以转换为任何其他分配器&LT;吨&gt;中我们可以简化
   //初始化服用只是一个分配器为所有内部容器。
   的typedef void_allocator allocator_type;   complex_data(complex_data常量和放大器;另外,常量allocator_type&安培; void_alloc)
       :ID_(other.id_),char_string_(other.char_string_,void_alloc),int_vector_(other.int_vector_,void_alloc)
   {}
   complex_data(常量allocator_type&安培; void_alloc)
      :ID _( - 1),char_string_(void_alloc),int_vector_(void_alloc)
   {}
   //其他成员...
   //
};的typedef void_allocator ::重新绑定&LT; complex_data&GT; ::其他complex_data_allocator;
typedef的矢量&lt; complex_data,complex_data_allocator&GT; complex_data_vector;诠释的main()
{
   //删除建设和破坏共享内存
   结构shm_remove
   {
      shm_remove(){shared_memory_object ::删除(MySharedMemory); }
      〜shm_remove(){shared_memory_object ::删除(MySharedMemory); }
   }卸妆;   //创建共享内存
   managed_shared_memory段(create_only,MySharedMemory,65536);   //一个分配器转换为任何分配器&LT; T,segment_manager_t&GT;类型
   void_allocator alloc_inst(segment.get_segment_manager());   //构建共享内存映射并填写
   complex_data * complex_data0_ = segment.construct&LT; complex_data&GT; (MyCompexData)(alloc_inst);   complex_data0 _-&GT; char_string_ =你好沃尔德;
   complex_data0 _-&GT; int_vector_.push_back(3);   complex_data * complex_data1_ = segment.find_or_construct&LT; complex_data&GT; (MyCompexData)(alloc_inst);
   complex_data1 _-&GT; int_vector_.push_back(6);   性病::法院LT&;&LT; complex_data1 _-&GT;&ID_ LT;&LT; ,&所述;&下; complex_data0 _-&GT; char_string_;
   用于(为size_t我= 0; I&LT; complex_data1 _-&GT; int_vector_.size();我++)的std ::法院LT&;&LT; ,&所述;&下; complex_data1 _-&GT; int_vector_ [I]
   complex_data_vector * complex_data_vector0 = segment.construct&LT; complex_data_vector&GT; (MyCompexDataVector)(alloc_inst);   complex_data_vector0-&GT;调整(3);
   complex_data_vector0-&GT; emplace_back();
}

请注意我是如何做的 void_allocator 键入分配器定义重新绑定,使其更容易改变你的code中的'根分配器的实现。

I like to create a boost interprocess vector of classes containing a interprocess container. The following code works until the resize function call and of course because my class has not default constructor. How to I resolve this problem? The example is based on the boost Containers of containers example

Thanks Markus

#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/map.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/containers/string.hpp>

using namespace boost::interprocess;

//Typedefs of allocators and containers
typedef managed_shared_memory::segment_manager                       segment_manager_t;
typedef allocator<void, segment_manager_t>                           void_allocator;
typedef allocator<int, segment_manager_t>                            int_allocator;
typedef vector<int, int_allocator>                                   int_vector;
typedef allocator<char, segment_manager_t>                           char_allocator;
typedef basic_string<char, std::char_traits<char>, char_allocator>   char_string;

class complex_data
{
public:
   int               id_;
   char_string       char_string_;
   int_vector int_vector_;

   //Since void_allocator is convertible to any other allocator<T>, we can simplify
   //the initialization taking just one allocator for all inner containers.
   complex_data(const void_allocator &void_alloc)
      : id_(-1), char_string_(void_alloc), int_vector_(void_alloc)
   {}
   //Other members...
};


typedef allocator<complex_data, segment_manager_t>     complex_data_allocator;
typedef vector<complex_data, complex_data_allocator>   complex_data_vector;

int main ()
{
   //Remove shared memory on construction and destruction
   struct shm_remove
   {
      shm_remove() { shared_memory_object::remove("MySharedMemory"); }
      ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); }
   } remover;

   //Create shared memory
   managed_shared_memory segment(create_only,"MySharedMemory", 65536);

   //An allocator convertible to any allocator<T, segment_manager_t> type
   void_allocator alloc_inst (segment.get_segment_manager());

   //Construct the shared memory map and fill it
   complex_data *complex_data0_ = segment.construct<complex_data> ("MyCompexData")(alloc_inst);

   complex_data0_->char_string_ = "Hello Wold";
   complex_data0_->int_vector_.push_back(3);

   complex_data *complex_data1_ = segment.find_or_construct<complex_data> ("MyCompexData")(alloc_inst);
   complex_data1_->int_vector_.push_back(6);

   std::cout << complex_data1_->id_ << ", " << complex_data0_->char_string_;
   for(size_t i = 0; i < complex_data1_->int_vector_.size(); i++) std::cout << ", " << complex_data1_->int_vector_[i];


   complex_data_vector *complex_data_vector0 = segment.construct<complex_data_vector> ("MyCompexDataVector")(alloc_inst);

   /**
    * Problem
    * How to I resize or add new elements?
    **/
   complex_data_vector0->resize(3);  


   return 0;
}

解决方案

REWRITE

As Boost Containers support the scoped allocator pattern, you can just use a scoped allocator, and the container will automatically pass it on internal construction (or emplacing) of new elements, when that element has the uses_allocator<> trait specialized positively for it:

Live On Coliru

#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/container/scoped_allocator.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/map.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/containers/string.hpp>

using namespace boost::interprocess;

//Typedefs of allocators and containers
typedef managed_shared_memory::segment_manager                       segment_manager_t;
typedef boost::container::scoped_allocator_adaptor<allocator<void, segment_manager_t> >
                                                                     void_allocator;
typedef void_allocator::rebind<int>::other                           int_allocator;
typedef vector<int, int_allocator>                                   int_vector;

typedef void_allocator::rebind<char>::other                          char_allocator;
typedef basic_string<char, std::char_traits<char>, char_allocator>   char_string;

class complex_data
{
public:
   int               id_;
   char_string       char_string_;
   int_vector int_vector_;

   //Since void_allocator is convertible to any other allocator<T>, we can simplify
   //the initialization taking just one allocator for all inner containers.
   typedef void_allocator allocator_type;

   complex_data(complex_data const& other, const allocator_type &void_alloc)
       : id_(other.id_), char_string_(other.char_string_, void_alloc), int_vector_(other.int_vector_, void_alloc)
   {}
   complex_data(const allocator_type &void_alloc)
      : id_(-1), char_string_(void_alloc), int_vector_(void_alloc)
   {}
   //Other members...
   //
};

typedef void_allocator::rebind<complex_data>::other    complex_data_allocator;
typedef vector<complex_data, complex_data_allocator>   complex_data_vector;

int main ()
{
   //Remove shared memory on construction and destruction
   struct shm_remove
   {
      shm_remove() { shared_memory_object::remove("MySharedMemory"); }
      ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); }
   } remover;

   //Create shared memory
   managed_shared_memory segment(create_only,"MySharedMemory", 65536);

   //An allocator convertible to any allocator<T, segment_manager_t> type
   void_allocator alloc_inst (segment.get_segment_manager());

   //Construct the shared memory map and fill it
   complex_data *complex_data0_ = segment.construct<complex_data> ("MyCompexData")(alloc_inst);

   complex_data0_->char_string_ = "Hello Wold";
   complex_data0_->int_vector_.push_back(3);

   complex_data *complex_data1_ = segment.find_or_construct<complex_data> ("MyCompexData")(alloc_inst);
   complex_data1_->int_vector_.push_back(6);

   std::cout << complex_data1_->id_ << ", " << complex_data0_->char_string_;
   for(size_t i = 0; i < complex_data1_->int_vector_.size(); i++) std::cout << ", " << complex_data1_->int_vector_[i];


   complex_data_vector *complex_data_vector0 = segment.construct<complex_data_vector> ("MyCompexDataVector")(alloc_inst);

   complex_data_vector0->resize(3);
   complex_data_vector0->emplace_back();
}

Note how I made the allocator definitions rebinds of the void_allocator type, making it much easier to change the 'root allocator' implementation for your code.

这篇关于如何创建进程间集装箱升压进程间矢量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆