boost не может переместить scoped_lock с помощью gcc

Следующие компиляции под VS2010 (Express), но не GCC (4.6.2 здесь).

Lockable.h:

#include <boost/thread/mutex.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>

template<typename T>
class LockedProxy : boost::noncopyable
{
public:
inline LockedProxy(boost::mutex & m, T * obj)
:lock(m),
t(obj)
{}
inline LockedProxy(const LockedProxy && other)
:lock(std::move(other.lock)),
t(std::move(other.t))
{}

inline       T * operator->()       { return t; }
inline const T * operator->() const { return t; }

inline const T & operator*() const { return *t; }
inline       T & operator*()       { return *t; }

private:
boost::interprocess::scoped_lock<boost::mutex> lock;
T * t;
};template<typename T>
class Lockable
{
public:

// Convenience typefed for subclasses to use
typedef T LockableObjectType;

inline Lockable(const T & t)
:lockableObject(t)
{}

inline LockedProxy<LockableObjectType> GetLockedProxy() {
return LockedProxy<LockableObjectType>(mutex, &lockableObject);
}

protected:
LockableObjectType lockableObject;
boost::mutex mutex;
};

main.cpp:

#include <iostream>
#include <string.h>
#include "Lockable.h"
void f(Lockable<std::string> & str)
{
auto proxy = str.GetLockedProxy();

*proxy = "aa";
proxy->append("bb");

std::cout << "str = " << *proxy << std::endl;
}

void g(Lockable<int> & i)
{
{ // reduce lock's lifespan
auto proxy = i.GetLockedProxy();
*proxy = 321;
}

// relock, lock lives for the statement
std::cout << "i = " << *i.GetLockedProxy() << std::endl;
}

int main()
{
Lockable<std::string> str("abc");
//Can't use str here, it is not locked
f(str);

Lockable<int> i(123);
g(i);

return 0;
}

Ошибки:

In file included from main.cpp:3:0:
C:/Users/DrGibbs/Documents/code/boost_1_46_0/boost/interprocess/sync/scoped_lock.hpp: In constructor 'LockedProxy<T>::LockedProxy(const LockedProxy<T>&&) [with T = std::basic_string<char>, LockedProxy<T> = LockedProxy<std::basic_string<char> >]':main.cpp:7:37:   instantiated from here
C:/Users/DrGibbs/Documents/code/boost_1_46_0/boost/interprocess/sync/scoped_lock.hpp:56:4: error: 'boost::interprocess::scoped_lock<Mutex>::scoped_lock(const boost::interprocess::scoped_lock<Mutex>&)[with Mutex = boost::mutex, boost::interprocess::scoped_lock<Mutex> = boost::interprocess::scoped_lock<boost::mutex>]' is privateLockable.h:14:29: error: within this context
C:/Users/DrGibbs/Documents/code/boost_1_46_0/boost/interprocess/sync/scoped_lock.hpp: In constructor 'LockedProxy<T>::LockedProxy(const LockedProxy<T>&&) [with T = int, LockedProxy<T> = LockedProxy<int>]':
main.cpp:18:36:   instantiated from here
C:/Users/DrGibbs/Documents/code/boost_1_46_0/boost/interprocess/sync/scoped_lock.hpp:56:4: error: 'boost::interprocess::scoped_lock<Mutex>::scoped_lock(const boost::interprocess::scoped_lock<Mutex>&)[with Mutex = boost::mutex, boost::interprocess::scoped_lock<Mutex> = boost::interprocess::scoped_lock<boost::mutex>]' is private
Lockable.h:14:29: error: within this context

Ну, насколько я понимаю, в LockedProxyход-конструктор scoped_lock не перемещается, а копируется, что действительно не должно работать. Не должен std::move гарантировать его ход-строительство? Что мне не хватает?

0

Решение

Ваш конструктор перемещения объявляет свой параметр const:

inline LockedProxy(const LockedProxy && other)

Должно быть объявлено неконстантным:

inline LockedProxy(LockedProxy && other)

Ваш std::move(other.lock) принимает other.lock в качестве ссылки на констант и, таким образом, возвращая ссылку на константное значение const boost::interprocess::scoped_lock<boost::mutex> &&, который нельзя передать конструктору перемещения boost::interprocess::scoped_lock<boost::mutex>,

Смотрите также C ++ 0x const RValue ссылка в качестве параметра функции, что объясняет, что ссылки на константные значения почти полностью бесполезны.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]