[英]std::unique_ptr and templates: Why won't this code compile?
I am working on a templated component system for a game. 我正在为游戏创建模板化的组件系统。 It holds items in a vector and has two partial specializations: One for POD types and another that uses std::unique_ptr.
它在矢量中保存项目,并具有两个部分的专业化:一个用于POD类型,另一个用于std :: unique_ptr。 The templated specialization for the vector of std::unique_ptr doesn't compile but using a vector of std::unique_ptr's in non-templated code works fine.
std :: unique_ptr的向量的模板专用化不能编译,但是在非模板代码中使用std :: unique_ptr的向量可以正常工作。 I have searched for a solution to this problem, but unfortunately my knownledge of C++11/C++14 isn't refined enough;
我已经在寻找解决此问题的方法,但是不幸的是,我对C ++ 11 / C ++ 14的了解还不够。 what am I doing wrong?
我究竟做错了什么?
Minimal example (stripped to the problem area): 最小示例(跳至问题区域):
#include <vector>
#include <memory>
template<typename T>
class component
{
public:
class handle
{
friend class component;
protected:
std::size_t inner;
};
component<T>::handle add(const T& t)
{
items.push_back(t);
handle h;
h.inner = items.size() - 1;
return h;
}
protected:
std::vector<T> items;
};
template<typename T>
class component<std::unique_ptr<T>>
{
public:
class handle
{
friend class component;
protected:
std::size_t inner;
};
component<std::unique_ptr<T>>::handle add(const std::unique_ptr<T>& t)
{
items.push_back(std::move(t));
handle h;
h.inner = items.size() - 1;
return h;
}
protected:
std::vector<std::unique_ptr<T>> items;
};
Here is the testing code 这是测试代码
int main()
{
// This works fine.
component<int> pod_component;
pod_component.add(5);
// This works, too!
std::vector<std::unique_ptr<int>> pointer_vector;
pointer_vector.push_back(std::make_unique<int>(5));
component<std::unique_ptr<int>> pointer_component;
// Why doesn't this compile?
pointer_component.add(std::make_unique<int>(5));
return 0;
}
Here is the error output from gcc (4.9.3 Gentoo): 这是gcc(4.9.3 Gentoo)的错误输出:
error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp = std::default_delete<int>]’
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
I hope that someone better at C++ than myself can help both me and future readers understand this tricky question. 我希望比我自己更擅长C ++的人可以帮助我和未来的读者理解这个棘手的问题。
The problem is here: 问题在这里:
component<std::unique_ptr<T>>::handle add(const std::unique_ptr<T>& t)
{ // |
items.push_back(std::move(t));// <------+
// ...
std::move
applied to a const
lvalue returns a const
rvalue reference. std::move
应用于const
左值将返回const
右值引用。 Thus, it is bound by the push_back(const value_type&)
overload rather than the push_back(value_type&&)
one, which means that it tries to copy the unique_ptr
passed as an argument. 因此,它受
push_back(const value_type&)
重载约束,而不是受push_back(value_type&&)
push_back(const value_type&)
重载约束,这意味着它试图复制作为参数传递的unique_ptr
。
The correct declaration should look as follows: 正确的声明应如下所示:
component<std::unique_ptr<T>>::handle add(std::unique_ptr<T>&& t)
// ~^^~
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.