Как мне назначить boost :: interprocess :: unique_ptr, возвращенный из фабричной функции, возможно, используя boost :: move, в C ++ 03

Я пытаюсь создать фабричную функцию, которая будет возвращать boost :: interprocess :: unique_ptr. Вот пример:

#include <boost/interprocess/smart_ptr/unique_ptr.hpp>
using namespace boost::interprocess;

class my_class {
public:
my_class() {}
};

struct my_class_deleter {
void operator()(my_class *p) {}
};

typedef unique_ptr<my_class, my_class_deleter> uptr;

uptr create() {
return uptr();
}

int main() {
uptr x;
x = create();
return 0;
}

Проблема в том, что gcc не может скомпилировать приведенный выше код:

main.cpp:22: error: ambiguous overload for ‘operator=’ in ‘x = create()()’
../../boost_latest/boost/interprocess/smart_ptr/unique_ptr.hpp:211: note: candidates are: boost::interprocess::unique_ptr<T, D>& boost::interprocess::unique_ptr<T, D>::operator=(boost::rv<boost::interprocess::unique_ptr<T, D> >&) [with T = my_class, D = my_class_deleter]
../../boost_latest/boost/interprocess/smart_ptr/unique_ptr.hpp:249: note:                 boost::interprocess::unique_ptr<T, D>& boost::interprocess::unique_ptr<T, D>::operator=(int boost::interprocess::unique_ptr<T, D>::nat::*) [with T = my_class, D = my_class_deleter]

Когда я меняюсь

x = create();

в

x = boost::move(create());

тогда gcc говорит:

main.cpp:22: error: invalid initialization of non-const reference of type ‘uptr&’ from a temporary of type ‘uptr’
../../boost_latest/boost/move/move.hpp:330: error: in passing argument 1 of ‘typename boost::move_detail::enable_if<boost::has_move_emulation_enabled<T>, boost::rv<T>&>::type boost::move(T&) [with T = uptr]’

Я делаю что-то неправильно?

Интересно, когда я это сделаю

uptr x2 = create();

код компилируется без проблем.

Кстати: я использую gcc v4.4.3 и Boost v1.51.0.


ОБНОВИТЬ:

Я смог преодолеть эту проблему с помощью следующего фрагмента:

x = static_cast<boost::rv<uptr>&>(create());

Приведенное выше приведение основано на первой версии неоднозначной перегрузки для operator= упоминается в оригинальном вопросе. Второй (operator=(int boost::interprocess::unique_ptr<T, D>::nat::*), вероятно, обеспечивается реализацией для эмуляции std::unique_ptr::operator=(nullptr_t)который на самом деле сбрасывает unique_ptr, Оказывается, это также делает operator= неоднозначный.

К сожалению, используя вышеупомянутое static_cast<>() делает использование моей фабрики слишком сложным.

Одним из способов решения этой проблемы будет удаление второй перегрузки для operator=, как всегда можно явно unique_ptr::reset(),

Тем не менее, мне интересно, если и как boost::move() мог бы помочь мне с этим вопросом.

3

Решение

Это оказалось ошибкой в ​​реализации boost::interprocess:unique_ptr,

Я сообщил об этом сопровождающему библиотеки (билет № 7598).

Ошибка была исправлена, и исправление будет доступно в Boost v1.54.0.

3

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

Не уверен, что он соответствует вашему сценарию использования, но вместо использования unique_ptr, вы не можете сделать my_class подвижным типом (с Boost :: Move) и делать вещи по значению, используя Boost ValueFactory для интерфейса фабрики?

0