我正在尝试创建一个返回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();
代码编译没有任何问题。
BTW:我使用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()
是否以及如何帮助我解决这个问题。
答案 0 :(得分:3)
这是boost::interprocess:unique_ptr
实施中的一个错误。
我向图书馆的维护者报告(ticket #7598)。
该错误已得到修复,修复程序将在Boost v1.54.0中提供。
答案 1 :(得分:0)
不确定它是否符合您的用例,而不是使用unique_ptr,您不能将my_class设置为可移动类型(使用Boost :: Move)并使用Boost ValueFactory为工厂接口按值执行操作吗?