在梳理了Boost :: Interprocess文档和Google搜索之后,我想我已经找到了解决问题的原因/解决方法。正如我所理解的那样,我发现的所有东西似乎都暗示着这一点,但并没有出来说“做这个因为......”。但如果有人能证实这一点我会很感激。
我正在编写一系列类,这些类表示存储在内存中的大量信息查找,以便在并行化应用程序中实现快速性能。由于数据的大小和一台机器上一次运行的多个进程,我们使用Boost :: Interprocess共享内存来获得结构的单个副本。
我查看了Boost :: Interprocess文档和示例,他们为共享内存字符串,字符串向量,int向量向量等类型定义了类。当他们在他们的示例中“使用”它们时,他们只是构造它们通过分配器并可能插入一个他们在其他地方构建的项目。就像在这个页面上一样:http://www.boost.org/doc/libs/1_42_0/doc/html/interprocess/allocators_containers.html
因此,按照他们的示例,我为共享内存类创建了一个带有typedef的头文件:
namespace shm {
namespace bip = boost::interprocess;
// General/Utility Types
typedef bip::managed_shared_memory::segment_manager segment_manager_t;
typedef bip::allocator<void, segment_manager_t> void_allocator;
// Integer Types
typedef bip::allocator<int, segment_manager_t> int_allocator;
typedef bip::vector<int, int_allocator> int_vector;
// String Types
typedef bip::allocator<char, segment_manager_t> char_allocator;
typedef bip::basic_string<char, std::char_traits<char>, char_allocator> string;
typedef bip::allocator<string, segment_manager_t> string_allocator;
typedef bip::vector<string, string_allocator> string_vector;
typedef bip::allocator<string_vector, segment_manager_t> string_vector_allocator;
typedef bip::vector<string_vector, string_vector_allocator> string_vector_vector;
}
然后,对于我的一个查找表类,它的定义如下:
class Details {
public:
Details(const shm::void_allocator & alloc) :
m_Ids(alloc),
m_Labels(alloc),
m_Values(alloc) {
}
~Details() {}
int Read(BinaryReader & br);
private:
shm::int_vector m_Ids;
shm::string_vector m_Labels;
shm::string_vector_vector m_Values;
};
int Details::Read(BinaryReader & br) {
int num = br.ReadInt();
m_Ids.resize(num);
m_Labels.resize(num);
m_Values.resize(num);
for (int i = 0; i < num; i++) {
m_Ids[i] = br.ReadInt();
m_Labels[i] = br.ReadString().c_str();
int count = br.ReadInt();
m_Value[i].resize(count);
for (int j = 0; j < count; j++) {
m_Value[i][j] = br.ReadString().c_str();
}
}
}
但是当我编译它时,我得到错误:
'boost::interprocess::allocator<T,SegmentManager>::allocator' : no appropriate default constructor available
这是由于对矢量对象的resize()
调用所致。因为allocator
类型没有空构造函数(它们采用const segment_manager_t &
)并且它正在尝试为每个位置创建一个默认对象。所以为了使它工作,我必须得到一个allocator对象并在resize
上传递一个默认值对象。像这样:
int Details::Read(BinaryReader & br) {
shm::void_allocator alloc(m_Ids.get_allocator());
int num = br.ReadInt();
m_Ids.resize(num);
m_Labels.resize(num, shm::string(alloc));
m_Values.resize(num, shm::string_vector(alloc));
for (int i = 0; i < num; i++) {
m_Ids[i] = br.ReadInt();
m_Labels[i] = br.ReadString().c_str();
int count = br.ReadInt();
m_Value[i].resize(count, shm::string(alloc));
for (int j = 0; j < count; j++) {
m_Value[i][j] = br.ReadString().c_str();
}
}
}
这是最佳/正确的做法吗?或者我错过了什么。
谢谢!