tow*_*owi 2 c++ unique-ptr c++11
在N2812中是引言中的一个例子,其中a 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
}
Run Code Online (Sandbox Code Playgroud)
本文讨论了RValue/LValue重载分辨率的问题,但这不是我的观点.
我想知道,如果提供参数std::unique_ptr<int> a by-value不会导致编译器错误?它会复制它,对吗?这是不允许的unique_ptr
我知道这篇论文很老了,也许这个定义unique_ptr已经改变了.但也许这只是一个错字,而作者想要写作std::unique_ptr<int> &a呢?
我的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
}
Run Code Online (Sandbox Code Playgroud)
按值获取参数没有任何问题.您是正确的,如果您尝试使用副本初始化参数,您将收到编译器错误,因为该函数已被删除.但是,您可以通过提供rvalue作为参数来初始化value参数.例如:
std::unique_ptr<int> myPtr{ /* ... */ }
std::list<std::unique_ptr<int>> elems;
push_back2(elems, myPtr); // Error, as you've noted
push_back2(elems, std::move(myPtr)); // Fine, uses move constructor to initialize
Run Code Online (Sandbox Code Playgroud)
这种语法很好,因为它会强制您明确指示您将指针移交给函数.
一旦你进入push_back2,你是正确的,push_back将无法接受,unique_ptr因为它将尝试使用不存在的复制构造函数.要解决此问题,您需要std::move再次使用:
void push_back2(
std::list<std::unique_ptr<int>>& l, std::unique_ptr<int> a)
{
l.push_back(std::move(a)); // Fine, moves a
l.push_back(std::move(a)); // Well that was dumb, but you asked for it!
}
Run Code Online (Sandbox Code Playgroud)
我希望我正确地解释你的问题,这就是你正在寻找的......让我知道,如果还有什么我可以尝试澄清的!
| 归档时间: |
|
| 查看次数: |
1164 次 |
| 最近记录: |