【发布时间】:2022-10-21 13:30:08
【问题描述】:
我试图从一个函数返回一个vector<unique_ptr>,但我遇到了错误。我正在使用 MSVC 19.33.31630。
this question 的 cmets 建议按值返回,但此代码:
std::vector<std::unique_ptr<int>> test1()
{
std::vector<std::unique_ptr<int>> ret = { std::make_unique<int>(1) };
return ret;
}
int main()
{
std::vector<std::unique_ptr<int>> x = test1();
std::unique_ptr<int>& ptrY = x.at(0);
return 0;
}
产生此错误:
错误 C2280 'std::unique_ptr<int,std::default_delete<int>>::unique_ptr(const std::unique_ptr<int,std::default_delete<int>> &)':试图引用已删除的函数
通过引用返回,如下代码:
std::vector<std::unique_ptr<int>>& test2() { std::vector<std::unique_ptr<int>> ret = { std::make_unique<int>(1) }; return ret; } int main() { std::vector<std::unique_ptr<int>>& y = test2(); std::cout << *(y.at(0)) << std::endl; return 0; }产生相同的错误。
为什么会这样?
unique_ptr的所有权是否没有正确转移?
【问题讨论】:
-
有趣的事实:这是不返回任何内容的代码:godbolt.org/z/zo1WWseMz
unique_ptr被复制到initializer_list中,这就是复制的位置。 -
避免复制,所以使用
return std::make_unique<T>()或auto ptr = std::make_unique<T>(); .. do something with p .. return p;如果你愿意,你可以从测试 2 中返回auto。 -
test2只要通过引用返回就注定会遭遇不幸。返回对局部变量的引用是不可能的。据报道,test1和test2有相同的错误信息,这让我更仔细地研究了它。通过引用返回没有返回副本,因此如果出现相同的错误,则副本必须在其他地方。 -
寻找一个好的副本brought this question up。作为一个骗子,我不愿意关闭,因为这没有给出答案,但我没有看到答案。即使您将
move复制到initializer_list,initializer_list仍然会被复制到vector。您可能会遇到emplace_backs 的块。 -
这看起来像是一个可行的副本(但我可能会有偏见,因为它回答了我关于为什么你不能搬出
initializer_list的问题 - DUH!它是const):Any way to initialize a vector of unique_ptr?