C++0x unique_ptr 误解?
在 N2812 中是一个示例简介,其中将unique_ptr
作为值参数给出。
void push_back2(
std::list<std::unique_ptr<int>>& l, std::unique_ptr<int> a)
{
l.push_back(a); // oops: moves from the lvalue 'a', silently!
l.push_back(a); // oops: 'a' no longer has its original value
}
本文讨论了RValue/LValue重载的问题决议,但这不是我的观点。
我想知道是否提供参数 std::unique_ptrunique_ptr
来说这是不允许的,
我知道这篇论文已经很旧了,也许从那以后 unique_ptr
的定义已经改变了。但也许这只是一个错字,作者想写成 std::unique_ptr
?
我的 gcc 4.7.0 同意我的观点,但这没有证据:-)
void push_back2( std::list<std::unique_ptr<int>>&, std::unique_ptr<int> ) { };
int main() {
list<unique_ptr<int>> lst;
unique_ptr<int> num { new int{4} };
push_back2(lst, num); //ERR: use of deleted function
}
In N2812 is an example in the Introduction where a unique_ptr
is given as a value parameter
void push_back2(
std::list<std::unique_ptr<int>>& l, std::unique_ptr<int> a)
{
l.push_back(a); // oops: moves from the lvalue 'a', silently!
l.push_back(a); // oops: 'a' no longer has its original value
}
The paper discusses a problem with RValue/LValue overload resolution, but thats not my point.
I wonder, if providing the argument std::unique_ptr<int> a
by-value is not causing a compiler error? It would copy it, right? And that is not allowed for unique_ptr
I am aware that the paper is quite old, maybe the definition of unique_ptr
has changed, since. But maybe it's just a typo and the author wanted to write std::unique_ptr<int> &a
instead?
My gcc 4.7.0 agrees with me, but thats no proof :-)
void push_back2( std::list<std::unique_ptr<int>>&, std::unique_ptr<int> ) { };
int main() {
list<unique_ptr<int>> lst;
unique_ptr<int> num { new int{4} };
push_back2(lst, num); //ERR: use of deleted function
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
按值获取参数没有任何问题。您是正确的,如果您尝试使用副本初始化参数,您将收到编译器错误,因为该函数已被删除。但是,您可以通过提供右值作为参数来初始化 value 参数。例如:
这种语法很好,因为它强制您明确指示您正在将指针移交给函数。
一旦进入
push_back2
,您就知道push_back
将无法接收unique_ptr
,因为它会尝试使用不存在的复制构造函数。要解决此问题,您需要再次使用std::move
:我希望我正确解释了您的问题,并且这就是您正在寻找的内容...如果有什么问题请告诉我否则我可以尝试澄清!
There's nothing wrong with taking the parameter by value. You are correct that if you try to initialize the parameter by using a copy, you will get a compiler error since that function is deleted. However, you could initialize the value parameter by providing an rvalue as the argument. For example:
This syntax is nice in that it forces you to explicitly indicate that you're handing the pointer over to the function.
Once you're inside
push_back2
, you are correct thatpush_back
won't be able to take in theunique_ptr
because it will try to use the nonexistent copy constructor. To fix this, you'll need to usestd::move
again:I hope that I interpreted your question correctly and that this is what you're looking for... let me know if there's anything else I can try to clarify!
您对该行为的了解和假设是正确的。
该论文的示例令人困惑,因为它将两种语言混为一谈:带有概念的 C++ 和没有概念的 C++。在论文的假装语言中,需要
CopyConstructible
的list
Push_back 被 SFINAE 去掉,只留下需要MoveConstructible
的重载。在这样的list
设计中,并且使用左值可以绑定到右值引用的旧规则,那么push_back
将隐式移动来自a
两次。请注意,
list
实际上以这种方式表现,我们在任何时候都不会遇到危险。作者只是试图设置一种情况,其中const value_type&
和value_type&&
没有重载,并且您只有value_type&&
code> 在重载集中。Your knowledge and assumptions about the behavior are correct.
The paper's example is confusing as it is conflating two languages: C++ with concepts and C++ without concepts. In the paper's pretend language, the
list
push_back which requiresCopyConstructible
is SFINAE'd away, leaving only the overload requiringMoveConstructible
. In such alist
design, and with the old rules that an lvalue could bind to an rvalue-reference, then thepush_back
would have implicitly moved froma
twice.Note that we were in no danger at any time of
list
actually behaving this way. The authors were simply trying to set up a situation whereconst value_type&
andvalue_type&&
were not overloaded, and you had onlyvalue_type&&
in the overload set.您可以通过右值提供它,例如通过函数返回。
此外,您可以显式
std::move
到列表中。You can provide it by rvalue- for example, by function return.
In addition, you can explicitly
std::move
into the list.