1

У меня есть следующий класс шаблона UtlSharedIPCWrapper, который я создал, доступ к определенному пользователю типу, который помещается в память между процессами.шаблон мета-программирования как специализироваться на коллекции

Обычно этот класс используется с помощью простого типа, например:

// construct a FaultReport - default to no faults 
auto faultWrapper = managed_shm.construct< 
    UtlSharedIPCWrapper<uint64_t>>("FaultReport")(0); 

и это работает хорошо, но я недавно имел необходимость использовать повышающий общий сбор карты памяти (boost::interprocess::map) в качестве аргумента шаблона) как в:

using char_allocator = boost::interprocess::managed_shared_memory::allocator<char>::type; 
using shm_string = boost::interprocess::basic_string<char, std::char_traits<char>, char_allocator>; 
using KeyType = shm_string; 
using ValueType = std::pair<const KeyType, shm_string>; 
using ShmemAllocator = boost::interprocess::allocator<ValueType, boost::interprocess::managed_shared_memory::segment_manager>; 
using SharedMemoryMap = boost::interprocess::map<shm_string, shm_string, std::less<KeyType>, ShmemAllocator>; 

... 

// create a new shared memory segment 2K size 
managed_shared_memory managed_shm(open_only, "sharedmemname"); 

//Initialize the shared memory STL-compatible allocator 
ShmemAllocator alloc(managed_shm.get_segment_manager()); 

auto pSharedNVPairs = managed_shm.find<UtlSharedIPCWrapper< 
    SharedMemoryMap>>("NameValuePairs").first; 

мой вопрос, как я могу изменить определение класса шаблона ниже, чтобы передать типы коллекций :: значения в качестве параметров, а не отдельно чтения всей карты в качестве одной операции через pSharedNVPairs->getSharedData() обновление т emporary map и снова записать его в общую память через pSharedNVPairs->setSharedData(*pSharedNVPairs). Я знаю, что это будет отличаться для типов, которые не являются коллекциями, и поэтому нужно будет выполнить некоторую магическую метапрограммирование макета, которая делает выборочное включение, если и т. Д., Но я хотел бы, чтобы в мой класс был добавлен метод, похожий на

// I don't know the correct signature here 
void setSharedDataValue(const T::value_type& rSharedDataValue) { 
    boost::interprocess::scoped_lock<upgradable_mutex_type> lock(mMutex); 
    ... not sure what to do here to update the collection 
} 

template<typename T> 
struct UtlSharedIPCWrapper { 
private: 
    using upgradable_mutex_type = boost::interprocess::interprocess_upgradable_mutex; 

    mutable upgradable_mutex_type mMutex; 
    /*volatile*/ T mSharedData; 
public: 
    // explicit constructor used to initialize directly from existing memory 
    explicit UtlSharedIPCWrapper(const T& rInitialValue) 
     : mSharedData(rInitialValue) 
    {} 

    T getSharedData() const { 
     boost::interprocess::sharable_lock<upgradable_mutex_type> lock(mMutex); 
     return mSharedData; 
    } 

    void setSharedData(const T& rSharedData) { 
     boost::interprocess::scoped_lock<upgradable_mutex_type> lock(mMutex); 
     // update the shared data copy mapped - scoped locked used if exception thrown 
     // a bit like the lock guard we normally use 
     this->mSharedData = rSharedData; 
    } 
}; 
+0

у меня есть подозрение, вы действительно хотите спросить - много - другой вопрос - в этом случае, пожалуйста, уточнить, продлив образец кода, чтобы быть самостоятельной containted – sehe

+0

@ Я согласен с тем, что вопрос может быть немного расплывчатым, однако у меня есть два разных случая, которые я хотел бы сделать выше, принимает простой интегральный тип, а другой - коллекцию. Я хотел бы знать, как использовать шаблонную магию, чтобы сделать соответствующие специализированные задания. – johnco3

+0

@Sehe using GCC 4.9.1 Я получаю ошибку ниже. Это заставляет меня думать, что мне действительно нужен какой-то механизм std :: enable_if, чтобы эффективно прокомментировать весь метод, если создание шаблона не является интегральным или более конкретным контейнером типа - что вы думаете? - Я не уверен, как это сделать. Ниже приведена сокращенная ошибка компилятора .. В файле, включенном из In instanceiation 'struct UtlSharedIPCWrapper ': ALBFDaemon.cpp: 347: 31: требуется здесь UtlSharedIPCWrapper.h: 49: 10: error: 'long long unsigned int 'не является классом, структурой или типом объединения – johnco3

ответ

1

Почему просто не

// I don't know the correct signature here 
void setSharedDataValue(const typename T::value_type& rSharedDataValue)  { 
    boost::interprocess::scoped_lock<upgradable_mutex_type> lock(mMutex); 
    mSharedData.insert(rSharedDataValue); 
} 
+0

Я пробовал выше с визуальной студией 2015, но я получаю: C2825: «T»: должен быть класс или пространство имен, за которым следует «::». Не уверен в синтаксисе. Конечно, цель предоставления T :: value_type - это именно то, что я хотел бы предоставить, поскольку в этом случае мне нужно вставить элемент std :: pair в std :: map, я не уверен, что произойдет с этим кодом в случай, когда у меня есть UtlSharedIPCWrapper - исчезнет ли этот метод - это целая метапрограмма, о которой я не понимаю. – johnco3

+1

MSVC имеет некоторые нестандартные поведения, связанные с поиском имен в шаблонах. Можете ли вы предоставить/автономный/пример, который воспроизводит вашу проблему? – sehe

Смежные вопросы