Я пытаюсь создать фабричную функцию, которая будет возвращать 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()
помочь мне с этой проблемой.