类 的 c++ IPC Boost::Interprocess 包含映射的向量

c++ IPC Boost::Interprocess vector of classes containing map

我想创建一个包含映射的 类 的增强进程间向量。 下面的代码是基于Container of Container and Creating Vectors in shared memory的例子,但是把这两个教程结合起来感觉很不知所措。我想我坚持在内存中构建“MyVec”。之后,代码无法编译。

这背后的原因是,将数据一次加载到内存中,并根据需要从不同的进程访问它。

谢谢!西蒙

#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;

// this is my original object
// goal: create a named shared memory object of std::vector<obj>
/*
class obj {
    public:
        int id = 0;
        std::string string = "NA";             //will switch to "char_string"
        std::map<int, std::string> map;
        bool equalsType(const int &input, const bool &inverse){
            if (id == -1)
            {
                return !inverse;
            }
            return id == input ? !inverse : inverse;
        };
}
*/

// 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 allocator<char, segment_manager_t> char_allocator;
typedef basic_string<char, std::char_traits<char>, char_allocator> char_string;

// Definition of the map holding a int as key and string as mapped type
typedef std::pair<const int, char_string> map_value_type;
typedef allocator<map_value_type, segment_manager_t> map_value_type_allocator;
typedef map<int, char_string, std::less<int>, map_value_type_allocator> map_type;

class complex_data // "boost version" of obj class
{
    int id_;
    char_string char_string_;
    map_type map_type_;

public:
    // 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(int id, const char *name, const void_allocator &void_alloc)
        : id_(id), char_string_(name, void_alloc), map_type_(void_alloc)
    {
    }
};

// Definition of the vector holding complex_data objects
typedef allocator<complex_data, segment_manager_t> complex_data_vector_allocator;
typedef vector<complex_data, complex_data_vector_allocator> complex_data_vector;
typedef vector<complex_data_vector, complex_data_vector_allocator> complex_data_vector_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());

    // Starting from here I'm completely lost
    // Construct the shared vector and fill it
    complex_data_vector_vector *myVec = segment.construct<complex_data_vector_vector>("MyVector")(alloc_inst);

    for (int i = 0; i < 100; ++i)
    {
        // Both key(string) and value(complex_data) need an allocator in their constructors
        int key_object(i);
        map_value_type mapped_object(i, "test", alloc_inst);
        map_value_type value(key_object, mapped_object);
        // Modify values and insert them in the map

        myVec->push_back(value)
    }
}

您想创建一个 类 的矢量,但创建一个 类 的矢量。

你只需要complex_data_vector,不需要你的complex_data_vector_vector

#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;

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 allocator<char, segment_manager_t> char_allocator;
typedef basic_string<char, std::char_traits<char>, char_allocator> char_string;
typedef std::pair<const int, char_string> map_value_type;
typedef allocator<map_value_type, segment_manager_t> map_value_type_allocator;
typedef map<int, char_string, std::less<int>, map_value_type_allocator> map_type;

class complex_data
{
    int id_;
    char_string char_string_;
    map_type map_type_;

public:
    complex_data(int id, const char* name, const void_allocator& void_alloc)
        : id_(id)
        , char_string_(name, void_alloc)
        , map_type_(void_alloc)
    {
    }

    void set(int key, const char* value) {
        map_type_.insert(map_value_type{key, {value, map_type_.get_allocator()}});
    }
};

// Definition of the vector holding complex_data objects
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());

    complex_data_vector* myVec = segment.construct<complex_data_vector>("MyVector")(alloc_inst);

    for (int i = 0; i < 100; ++i) {
        myVec->emplace_back(i, "test", alloc_inst);
        complex_data& data = myVec->back();
        data.set(42, "Test");
    }

}