我有
template<typename T>
class queue
{
private:
struct node
{
T data;
std::unique_ptr<node> next; //compile error on incomplete type
node(T&& data_):
data(std::move(data_))
{}
};
std::unique_ptr<node> head;
node* tail;
public:
queue():
tail(nullptr)
{}
我在VS10中的标记行上遇到编译错误。在这种情况下,我不应该被允许使用不完整的类型(实例化模板 - 构造函数 - 这里以int为例)?有解决办法吗?
修改
singlethreadedqueue.h(62): error C2079: 'queue<T>::node::next' uses undefined class 'std::unique_ptr<_Ty>'
1> with
1> [
1> T=MyClass
1> ]
1> and
1> [
1> _Ty=queue<MyClass>::node
1> ]
1> c:\program files\microsoft visual studio 10.0\vc\include\memory(2161) : see reference to class template instantiation 'queue<T>::node' being compiled
1> with
1> [
1> T=MyClass
1> ]
1> c:\program files\microsoft visual studio 10.0\vc\include\memory(2195) : see reference to class template instantiation 'std::_Unique_ptr_base<_Ty,_Dx,_Empty_deleter>' being compiled
1> with
1> [
1> _Ty=queue<MyClass>::node,
1> _Dx=std::default_delete<queue<MyClass>::node>,
1> _Empty_deleter=true
1> ]
1> singlethreadedqueue.h(69) : see reference to class template instantiation 'std::unique_ptr<_Ty>' being compiled
1> with
1> [
1> _Ty=queue<MyClass>::node
1> ]
1> : see reference to class template instantiation 'queue<T>' being compiled
1> with
1> [
1> T=MyClass
1> ]
答案 0 :(得分:4)
模板实例化点的完整类型要求归因于std::default_delete
,因此您可以通过提供自定义删除器来解决它。
struct node; // node_delete need to know 'node' is a type.
struct node_deleter
{ // std::unique_ptr needs 'node_deleter' to be complete.
void operator()(node* ptr); // forward-reference to avoid needing
}; // 'delete ptr' before the node is complete.
struct node
{
std::unique_ptr<node, node_deleter> next;
};
void node_deleter::operator()(node* ptr)
{
delete ptr;
}
请注意,我没有在MSVC中测试它,如果VC 11无法编译原始代码,可能应该尝试升级到VC 11或file a bug to Microsoft。
答案 1 :(得分:3)
您的代码看起来很好。在构造函数体和析构函数体中,类被认为是完整类型。
答案 2 :(得分:0)
如果您使用shared_ptr
代替unique_ptr
,则会编译(在VS2010上)。我猜测它的实现方式允许在shared_ptr
的情况下使用部分类(前向声明等),但不允许unique_ptr
。 boost::shared_ptr
的文档明确表示允许这样做,但我不知道VS2010是否“说”为什么他们为一个而不是另一个做这种行为。
我会说测试它,看看它是否符合您shared_ptr
的需求。这不是你想要的,但如果它有效,速度差异不是很大,那就可以了。