我有一个boost::interprocess Containers of containers类型的示例演示程序。 但我喜欢在我的进程内存中使用该类也是一个普通的类。 有人可以帮我写一个不带参数的构造函数,让我的当前进程内存初始化类。
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <shmfw/serialization/interprocess_vector.hpp>
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */
using namespace boost::interprocess;
//Alias an STL-like allocator of ints that allocates ints from the segment
typedef allocator<int, managed_shared_memory::segment_manager> ShmemAllocator;
//Alias a vector that uses the previous STL-like allocator
typedef vector<int, ShmemAllocator> MyVector;
typedef allocator<void, managed_shared_memory::segment_manager > void_allocator;
class MyStruct {
public:
MyVector myVector;
//Since void_allocator is convertible to any other allocator<T>, we can simplify
//the initialization taking just one allocator for all inner containers.
MyStruct ( const void_allocator &void_alloc )
: myVector ( void_alloc )
{}
// Thats what I like to have
//MyStruct ()
// : myVector ( ?? )
//{}
};
int main () {
// I would like to have something like that working and also the shm stuff below
// MyStruct x;
managed_shared_memory segment;
//A managed shared memory where we can construct objects
//associated with a c-string
try {
segment = managed_shared_memory( create_only, "MySharedMemory", 65536 );
} catch (...){
segment = managed_shared_memory( open_only, "MySharedMemory" );
}
//Initialize the STL-like allocator
const ShmemAllocator alloc_inst ( segment.get_segment_manager() );
MyStruct *myStruct_src = segment.find_or_construct<MyStruct> ( "MyStruct" ) ( alloc_inst );
srand (time(NULL));
myStruct_src->myVector.push_back ( rand() );
MyStruct *myStruct_des = segment.find_or_construct<MyStruct> ( "MyStruct" ) ( alloc_inst );
for ( size_t i = 0; i < myStruct_src->myVector.size(); i++ ) {
std::cout << i << ": " << myStruct_src->myVector[i] << " = " << myStruct_des->myVector[i] << std::endl;
if(myStruct_src->myVector[i] != myStruct_des->myVector[i]) {
std::cout << "Something went wrong!" << std::endl;
}
}
//segment.destroy<MyVector> ( "MyVector" );
return 0;
}
答案 0 :(得分:1)
如果更改分配器类型,则更改容器(这是编译时模板实例化的性质)。
从技术上讲,您可以设计一个类型擦除的分配器(àlastd::function
或boost::any_iterator
),但这可能会导致性能极差。此外,它仍然需要所有分配器在所有静态已知属性中对应,从而降低灵活性。
实际上,我建议只对MyStruct
类型的Allocator
进行模板化以用于任何嵌入式容器。然后专门在构造函数中使用这样的allocator:
// Variant to use on the heap:
using HeapStruct = MyStruct<std::allocator>;
// Variant to use in shared memory:
using ShmemStruct = MyStruct<BoundShmemAllocator>;
演示计划:
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/range/algorithm.hpp>
#include <iostream>
#include <cassert>
namespace bip = boost::interprocess;
template <typename T>
using BoundShmemAllocator = bip::allocator<T, bip::managed_shared_memory::segment_manager>;
///////////////////////////////////////////////////////////////
// Your MyStruct, templatized for an Allocator class template
template <template<typename...> class Allocator>
class MyStruct {
public:
bip::vector<int, Allocator<int> > ints;
bip::vector<double, Allocator<double> > doubles;
MyStruct(const Allocator<void>& void_alloc = {})
: ints(void_alloc),
doubles(void_alloc)
{}
};
// Variant to use on the heap:
using HeapStruct = MyStruct<std::allocator>;
// Variant to use in shared memory:
using ShmemStruct = MyStruct<BoundShmemAllocator>;
//
///////////////////////////////////////////////////////////////
int main() {
srand(time(NULL));
// You can have something like this working:
HeapStruct x; // and also the shm stuff below
std::generate_n(std::back_inserter(x.ints), 20, &std::rand);
std::generate_n(std::back_inserter(x.doubles), 20, &std::rand);
// A managed shared memory where we can construct objects
bip::managed_shared_memory segment = bip::managed_shared_memory(bip::open_or_create, "MySharedMemory", 65536);
BoundShmemAllocator<int> const shmem_alloc(segment.get_segment_manager());
auto src = segment.find_or_construct<ShmemStruct>("MyStruct")(shmem_alloc);
src->ints.insert(src->ints.end(), x.ints.begin(), x.ints.end());
src->doubles.insert(src->doubles.end(), x.doubles.begin(), x.doubles.end());
auto des = segment.find_or_construct<ShmemStruct>("MyStruct")(shmem_alloc);
std::cout << "-------------------------";
boost::copy(src->ints, std::ostream_iterator<int>(std::cout << "\nsrc ints: ", "; "));
boost::copy(des->ints, std::ostream_iterator<int>(std::cout << "\ndes ints: ", "; "));
std::cout << "\n-------------------------";
boost::copy(src->doubles, std::ostream_iterator<double>(std::cout << "\nsrc doubles: ", "; "));
boost::copy(des->doubles, std::ostream_iterator<double>(std::cout << "\ndes doubles: ", "; "));
assert(src->ints.size() == des->ints.size());
assert(src->doubles.size() == des->doubles.size());
assert(boost::mismatch(src->ints, des->ints) == std::make_pair(src->ints.end(), des->ints.end()));
assert(boost::mismatch(src->doubles, des->doubles) == std::make_pair(src->doubles.end(), des->doubles.end()));
segment.destroy<ShmemStruct>("MyStruct");
}