在梳理了 Boost::Interprocess 文档和 Google 搜索之后,我想我已经找到了问题的原因/解决方法。据我了解,我发现的一切似乎都在暗示这一点,但并没有说“这样做是因为……”。但是,如果有人可以验证这一点,我将不胜感激。
我正在编写一系列类,这些类表示存储在内存中的大量信息查找,以便在并行化应用程序中实现快速性能。由于数据的大小和同时在一台机器上运行的多个进程,我们使用 Boost::Interprocess 共享内存来拥有结构的单个副本。
我查看了 Boost::Interprocess 文档和示例,它们为共享内存字符串、字符串向量、int 向量向量等 typedef 类。当他们在示例中“使用”它们时,他们只是通过分配器构造它们,也许插入他们在其他地方构建的一项。喜欢这个页面: 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
类型没有空的构造函数(它们采用 a const segment_manager_t &
)并且它试图为每个位置创建一个默认对象。所以为了让它工作,我必须得到一个分配器对象并传递一个默认值对象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();
}
}
}
这是最好/正确的方法吗?或者我错过了什么。
谢谢!