C++ 创建一个安全的读写器向量

C++ 创建一个安全的读写器向量,c++,c++11,std,boost-thread,C++,C++11,Std,Boost Thread,受此启发,我正在尝试实现一个读写器vector,它可以通过线程同时安全地调用push_back() 一旦这个类就位,我就可以通过调用std::swap()来创建方法erase(),该方法交换目标项和最后一项,然后删除集合中的最后一项。这样,我认为性能应该是公平的,因为在集合中间删除一个项目不调用移动集合中的目标项的所有项。 不幸的是,以下代码: #include <vector> #include <boost/thread/shared_mutex.hpp> //sha

受此启发,我正在尝试实现一个读写器
vector
,它可以通过线程同时安全地调用
push_back()

一旦这个类就位,我就可以通过调用
std::swap()
来创建方法
erase()
,该方法交换目标项和最后一项,然后删除集合中的最后一项。这样,我认为性能应该是公平的,因为在集合中间删除一个项目不调用移动集合中的目标项的所有项。

不幸的是,以下代码:

#include <vector>
#include <boost/thread/shared_mutex.hpp> //shared_mutex
#include <memory> //shared_ptr
#include <utility> //swap()

template <class T>
class readers_writer_vector
{
    std::shared_ptr<boost::shared_mutex> pm;
    std::vector<T> data;
public:
    readers_writer_vector() :
        pm(new std::shared_ptr<boost::shared_mutex>){}
    void push_back(const T& item){
        boost::unique_lock<boost::shared_mutex> lock(*pm); //wrong design
        data.push_back(item);
    }
};

int main()
{
    readers_writer_vector<int> db;
    db.push_back(1);
    return 0;
}
#包括
#包括//共享\u互斥
#包括//shared\u ptr
#包括//swap()
样板
类读取器\编写器\向量
{
std::共享的ptr pm;
std::矢量数据;
公众:
读写器向量()
pm(新std::shared_ptr){}
无效推回(常数和项目){
boost::unique_lock锁(*pm);//设计错误
数据。推回(项目);
}
};
int main()
{
读写器向量数据库;
db.推回(1);
返回0;
}
产生以下编译错误:

/usr/include/c++/4.9/bits/shared_ptr_base.h:871:39: error: cannot convert ‘std::shared_ptr<boost::shared_mutex>*’ to ‘boost::shared_mutex*’ in initialization
         : _M_ptr(__p), _M_refcount(__p)

// g++ -std=c++11 -Iboost -lboost t.cpp
/usr/include/c++/4.9/bits/shared_ptr_base.h:871:39:错误:无法在初始化中将“std::shared_ptr*”转换为“boost::shared_mutex*”
:_M_ptr(_p),_M_refcount(_p)
//g++-std=c++11-Iboost-lboost t.cpp
我怎么修理它?求你了

编辑:

实施任务比我想象的要复杂得多。没过多久,我就遇到了@Danh警告过的问题。现在我得到了这些错误:

t.cpp:28:8: note: ‘i::i(const i&)’ is implicitly deleted because the default definition would be ill-formed:
 struct i {
        ^
t.cpp:28:8: error: use of deleted function      ‘readers_writer_vector<T>::readers_writer_vector(const readers_writer_vector<T>&) [with T = z]’
t.cpp:13:2: note: declared here 
  readers_writer_vector(readers_writer_vector const&) = delete;
t.cpp:28:8:注意:“i::i(const i&)”被隐式删除,因为默认定义的格式不正确:
结构一{
^
t、 cpp:28:8:错误:使用删除的函数“readers\u writer\u vector::readers\u writer\u vector(const readers\u writer\u vector&)[带t=z]”
t、 cpp:13:2:注:此处声明
readers\u writer\u vector(readers\u writer\u vector const&)=删除;
对于此版本:

template <class T>
class readers_writer_vector
{
    booster::shared_mutex m;
    std::vector<T> data;
public:
    readers_writer_vector() = default;
    readers_writer_vector(readers_writer_vector const&) = delete;
    void push_back(const T& item){
        booster::unique_lock<booster::shared_mutex> lock(m);
        data.push_back(item);
    }
    typename std::vector<T>::reference back(){
        return data.back();
    }
};

struct z {
    int zipcode;
    std::string address;
};

struct i {
    int id;
    readers_writer_vector<z> zipcodes;
};

int main()
{
    readers_writer_vector<i> db;
    db.push_back(i());
    auto &ii=db.back();
    ii.id=1;
    ii.zipcodes.push_back(z());

    auto &zz=ii.zipcodes.back();
    zz.zipcode=11;
    zz.address="aa";

    return 0;
}
模板
类读取器\编写器\向量
{
助推器::共享互斥锁m;
std::矢量数据;
公众:
readers\u writer\u vector()=默认值;
readers\u writer\u vector(readers\u writer\u vector const&)=删除;
无效推回(常数和项目){
增压器:独特的_锁(m);
数据。推回(项目);
}
typename std::vector::reference back(){
返回data.back();
}
};
结构z{
int-zipcode;
std::字符串地址;
};
结构一{
int-id;
读写器向量zipcodes;
};
int main()
{
读写器向量数据库;
db.推回(i());
auto&ii=db.back();
ii.id=1;
ii.zipcodes.向后推(z());
auto&zz=ii.zipcodes.back();
zz.zipcode=11;
zz.address=“aa”;
返回0;
}
除了修复现有错误之外,我还必须为
readers\u writer\u vector
实现迭代器,使这个类变得有用


我正在考虑是否应该继续…

因为
pm
std::shared\u ptr
而不是
std::shared\u ptr*
。您可以使用以下方法:

readers_writer_vector() :
    pm(std::make_shared<boost::shared_mutex>()){}
readers\u writer\u vector():
pm(std::make_shared()){

无论如何,为什么需要指针/智能指针?这更适合:

template <class T>
class readers_writer_vector
{
    boost::shared_mutex pm;
    std::vector<T> data;
public:
    void push_back(const T& item){
        boost::unique_lock<boost::shared_mutex> lock(pm);
        data.push_back(item);
    }
};
模板
类读取器\编写器\向量
{
boost::共享互斥器pm;
std::矢量数据;
公众:
无效推回(常数和项目){
boost::唯一的锁(pm);
数据。推回(项目);
}
};

您正在使用错误的类型初始化
pm
;实际上您已经

std::shared_ptr<> pm = new std::shared_ptr<>;

或者直接将互斥体作为成员,而不是使用共享指针。

我使用智能指针,因为我认为直接将互斥体放入容器(如
std::vector v;
)不会根据@T.E.D
编译。这一点的不幸含义是,互斥体不能直接放入容器中。容器需要能够安全地移动其内容,而使用互斥锁是无法做到这一点的。
和@Adrian Maire.shared mutex-between-container对meI来说没有意义。我不打算在容器之间共享互斥锁。现在我想t.E.D.谈论的是与我不同的用例。当你复制构建
阅读器时r_vector
从其他
读者_writer_vector
,您确实与原始代码共享了互斥锁,我的建议应该禁用Copy。我面临这个矛盾:复制构造函数无法禁用,因为
std::vector::push_back()
需要它。
pm(new boost::shared_mutex)