2016-04-07 33 views
5

Vorrei bloccare i tasti/indice in un'altra mappa in questo modo:Come usare un boost :: mutex come tipo mappato in std :: map?

std::map<int, boost::mutex> pointCloudsMutexes_; 
pointCloudsMutexes_[index].lock(); 

Tuttavia, sto ottenendo il seguente errore:

/usr/include/c++/4.8/bits/stl_pair.h:113: error: no matching function for call to 'boost::mutex::mutex(const boost::mutex&)' 
     : first(__a), second(__b) { } 
          ^

Sembra funzionare con std::vector, ma non con std::map. Che cosa sto facendo di sbagliato?

+2

ci si chiede quali requisiti abbiano portato alla decisione di progettazione che una mappa di mutex sia una soluzione valida. C'è probabilmente un modo molto più elegante per ottenere quello che vuoi. –

+0

Una hashmap concorrente – Raaj

+0

Questo disegno non sarà una mappa hash concorrente. Sarà una mappa non-simultanea di mutex. È necessario avvolgere l'intera mappa e proteggerla con un solo mutex. –

risposta

4

In C++ prima C++ 11, il tipo mappato di un std::map deve essere sia default-costruibile e copia-costruibile, quando si chiama operator[]. Tuttavia, boost::mutex è progettato in modo esplicito per non essere copia-costruibile, perché non è generalmente chiaro quale dovrebbe essere la semantica della copia di un mutex. A causa del fatto che boost::mutex non è possibile copiare, l'inserimento di tale valore utilizzando pointCloudsMutexes_[index] non riesce a essere compilato.

La soluzione migliore è quella di utilizzare alcuni puntatore condiviso per boost::mutex come tipo mappato, per esempio:

#include <boost/smart_ptr/shared_ptr.hpp> 
#include <boost/thread/mutex.hpp> 
#include <map> 

struct MyMutexWrapper { 
    MyMutexWrapper() : ptr(new boost::mutex()) {} 
    void lock() { ptr->lock(); } 
    void unlock() { ptr->unlock(); } 
    boost::shared_ptr<boost::mutex> ptr; 
}; 

int main() { 
    int const index = 42; 
    std::map<int, MyMutexWrapper> pm; 
    pm[index].lock(); 
} 

PS: C++ 11 rimosso il requisito per il tipo mappato per essere copia-costruibile.

+0

si dice '" C++ 11 ha rimosso il requisito per il tipo mappato come copy-constructible "', quindi il codice dell'autore dovrebbe essere compilato in C++ 11? –

+0

@AlexeyAndronov si. Ho appena provato l'esempio di codice della domanda e lo compila quando index è un 'int'. – jotik

+0

non sul mio MSVS2015 update2 con 'std :: map' e' std :: mutex' anche se X_x –

1

La mappa richiede un costruttore di copia, ma sfortunatamente boost::mutex non ha un costruttore di copie pubblico. Mutex dichiarato come segue:

class mutex 
{ 
private: 
    pthread_mutex_t m; 
public: 
    BOOST_THREAD_NO_COPYABLE(mutex) 

Non penso che il vettore funzioni, dovrebbe avere lo stesso problema. Puoi push_back un boost::mutex in vettoriale?

+0

non è "sfortunato" che un mutex mutex non sia copiabile - è estremamente fortunato. Rappresenta una struttura dati sottostante che non deve essere spostata. –

+0

@Richard Sono d'accordo :) –