I am trying to create a shared memory manager map in boost, along with a synchronization class for the map. I previously did something roughly the same with vectors and it worked fine. I get the error mentioned in the title while using maps. Am I doing this all wrong? Code in this repo
#include <iostream>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/map.hpp>
#include <boost/interprocess/sync/interprocess_condition.hpp>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/thread/lock_guard.hpp>
namespace node_cluster_cache {
using namespace boost;
using namespace boost::interprocess;
using std::pair;
typedef uint64_t int64;
typedef uint32_t int32;
typedef std::array<int32, SIZE> msg_arr;
typedef std::array<char, ACCESS_SIZE> access_name;
template<class T>
class SynchronizedMap {
public:
typedef allocator<T, managed_shared_memory::segment_manager> allocator_type;
typedef lock_guard<interprocess_mutex> lock;
private:
map<access_name, T, allocator_type> _map;
mutable interprocess_mutex io_mutex;
mutable interprocess_condition wait_condition;
public:
SynchronizedMap(allocator_type alloc) : _map(alloc) {};
void insert(const access_name name, T msg_part) {
lock _lock(io_mutex);
_map.insert(pair<access_name, T>(name, msg_part));
}
int32 size() const {
lock _lock(io_mutex);
return _map.size();
}
bool empty() const {
lock _lock(io_mutex);
return _map.empty();
}
void clear() {
lock _lock(io_mutex);
_map.clear();
}
bool erase(access_name name) {
lock _lock(io_mutex);
return _map.erase(name);
}
bool erase(typename map<access_name, T>::iterator it) {
lock _lock(io_mutex);
return _map.erase(it);
}
};
};
struct Message {
int64 bit_no;
int64 pid;
int64 part_no;
int64 size;
msg_arr data;
Message() {}
Message(int64 bn, int64 p, int64 pn, int64 s, msg_arr& d) {
bit_no = bn;
pid = p;
part_no = pn;
size = s;
safe_copy(data, d);
}
Message(int64 bn, int64 p, int64 s, msg_arr& d) {
bit_no = bn;
pid = p;
part_no = 0;
size = s;
safe_copy(data, d);
}
};
template<size_t N>
static inline void safe_copy(std::array<int32, N>& dst, std::array<int32, N>& src) {
#undef min
std::copy_n(src.data(), std::min(src.size(), N), dst.data());
dst.back() = 0;
}
this->shmem = new managed_shared_memory(create_only, "node_cluster_cache", SHMEM_SIZE);
this->alloc_inst = new SynchronizedMap<Message>::allocator_type(this->shmem->get_segment_manager());
this->cache_map = this->shmem->construct<SynchronizedMap<Message> >("data_vector")(*(this->alloc_inst));
msg_arr test{ 123,456,789 };
access_name name = { 't', 'e', '\0' };
int64 a = 1;
int64 b = 2;
Message c(a, b, 4, test);
this->cache_map->insert(name, c);
Severity Code Description Project File Line Suppression State
Error C2664
'node_cluster_cache::SynchronizedMap<node_cluster_cache::Message>::SynchronizedMap
(const node_cluster_cache::SynchronizedMap<node_cluster_cache::Message> &)': cannot convert argument 1 from
'boost::interprocess::allocator<T,boost::interprocess::segment_manager<CharType,MemoryAlgorithm,IndexType>>' to 'const
node_cluster_cache::SynchronizedMap<node_cluster_cache::Message> &' node-cluster-cache
C:\boost_1_74_0\boost\interprocess\detail\named_proxy.hpp 85
Changing allocator_type to the value pair and defining a comparator for std::array<char, ACCESS_SIZE> solved the issue.
typedef pair<const access_name, T> value_type;
typedef allocator<value_type, managed_shared_memory::segment_manager> allocator_type;
struct cmp_str {
bool operator()(access_name a, access_name b) const {
for (int i = 0; ; i++) {
if (a[i] != b[i]) {
return a[i] < b[i] ? -1 : 1;
}
if (a[i] == '\0') {
return 0;
}
}
}
};
map<access_name, T, cmp_str, allocator_type> _map;