Как мне назначить boost::interprocess::unique_ptr, возвращенный из фабричной функции, возможно, с использованием boost::move, в С++ 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();

to

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() помочь мне с этой проблемой.


person Adam Romanek    schedule 26.10.2012    source источник


Ответы (2)


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

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

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

person Adam Romanek    schedule 22.01.2013

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

person TPJ    schedule 22.11.2012