C++ unique_ptr 和映射
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3906295/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C++ unique_ptr and map
提问by Matt Joiner
I'm trying to use the C++0xunique_ptr
classinside a map
like so:
我正在尝试使用C++0xunique_ptr
类,map
如下所示:
// compile with `g++ main.cpp -std=gnu++0x`
#include <string.h>
#include <map>
#include <memory>
using namespace std;
struct Foo {
char *str;
Foo(char const *str_): str(strdup(str_)) {}
};
int main(void) {
typedef std::map<int, unique_ptr<Foo>> Bar;
Bar bar;
auto a = bar.insert(Bar::value_type(1, new Foo("one")));
return 0;
}
However GCC gives me the following error (shortened, I think this is the relevant part, please test on your own C++ compiler):
但是 GCC 给了我以下错误(缩短,我认为这是相关部分,请在您自己的 C++ 编译器上测试):
main.cpp:19: instantiated from here /usr/include/c++/4.4/bits/unique_ptr.h:214: error: deleted function ‘std::unique_ptr::unique_ptr(const std::unique_ptr&) [with _Tp = Foo, _Tp_Deleter = std::default_delete]' /usr/include/c++/4.4/bits/stl_pair.h:68: error: used here
I'm really not sure what I've done wrong, this works on MSVC. I have found very similarquestions, that seem alike, however their solutions do not work for me.
我真的不确定我做错了什么,这适用于 MSVC。我发现了非常相似的问题,看起来很相似,但是他们的解决方案对我不起作用。
matt@stanley:/media/data/src/c++0x-test$ gcc --version gcc-4.4.real (Ubuntu 4.4.3-4ubuntu5) 4.4.3
采纳答案by Matt Joiner
I don't believe it's possible to correctly use unique_ptr
in a map::insert
yet. Here's the GCC bug for it:
我不相信unique_ptr
在 a 中正确使用是可能的map::insert
。这是它的 GCC 错误:
Bug 44436 - [C++0x] Implement insert(&&)
and emplace*
in associative and unordered containers
错误 44436 - [C++0x]在关联和无序容器中实现insert(&&)
和emplace*
It looks like it may be fixed for GCC 4.6, but it won't build from SVN on vanilla Ubuntu 10.04.1 to confirm.
看起来它可能已针对 GCC 4.6 修复,但它不会在 vanilla Ubuntu 10.04.1 上从 SVN 构建以确认。
Update0
更新0
This is not working as of GCC svn r165422 (4.6.0).
从 GCC svn r165422 (4.6.0) 开始,这不起作用。
回答by sellibitze
First: Your class Foo is really a very bad approximation of std::string. I predict lots of memory leaks. (Search for "rule of three".)
第一:你的 Foo 类真的是 std::string 的一个非常糟糕的近似值。我预测会有很多内存泄漏。(搜索“三规则”。)
Second: A pointer is not implicitly convertible to a unique_ptr object (for safety reasons). But the templated pair constructor requires the arguments to be implicitlyconvertible to the respective value types. GCC seems to allow this but it is a bug. You have to create the unique_ptr object manually. Unfortunately the C++0x draft lacks the following, very useful function template that eases the creation of temporary unique_ptr objects. It's also exception-safe:
第二:指针不能隐式转换为 unique_ptr 对象(出于安全原因)。但是模板对构造函数要求参数可以隐式转换为相应的值类型。GCC 似乎允许这样做,但这是一个错误。您必须手动创建 unique_ptr 对象。不幸的是,C++0x 草案缺少以下非常有用的函数模板,可以简化临时 unique_ptr 对象的创建。它也是异常安全的:
template<class T, class...Args>
std::unique_ptr<T> make_unique(Args&&... args)
{
std::unique_ptr<T> ret (new T(std::forward<Args>(args)...));
return ret;
}
In addition, let's use the new emplacefunction instead of insert:
此外,让我们使用新的emplace函数而不是insert:
auto a = bar.emplace(1,make_unique<Foo>("one"));
emplaceforwards both arguments to the corresponding pair constructor.
emplace将两个参数转发给相应的对构造函数。
The actual problem you witnessed is that the pair constructor tried to copy a unique_ptr even though such an object is only "movable". It seems that GCC's C++0x support is not yet good enough to handle this situation correctly. From what I can tell, my line from above should work according to the current standard draft (N3126).
您目睹的实际问题是配对构造函数试图复制 unique_ptr 即使这样的对象只是“可移动”。似乎 GCC 的 C++0x 支持还不足以正确处理这种情况。据我所知,我上面的行应该根据当前的标准草案(N3126)工作。
Edit:I just tried the following as a workaround using GCC 4.5.1 in experimental C++0x mode:
编辑:我只是尝试了以下作为在实验性 C++0x 模式下使用 GCC 4.5.1 的解决方法:
map<int,unique_ptr<int> > themap;
themap[42].reset(new int(1729));
This is also supposed to work in the upcoming standard but GCC rejects it as well. Looks like you have to wait for GCC to support unique_ptr in maps and multimaps.
这也应该适用于即将发布的标准,但 GCC 也拒绝了它。看起来您必须等待 GCC 在地图和多地图中支持 unique_ptr 。
回答by karadoc
I've just been tinkering with unique_ptr in gcc 4.6.0. Here's some (very ugly) code which works correctly:
我刚刚在 gcc 4.6.0 中修改了 unique_ptr。这里有一些(非常丑陋的)代码可以正常工作:
std::map<int, std::unique_ptr<int> > table;
table.insert(std::pair<int, std::unique_ptr<int>>(15, std::unique_ptr<int>(new int(42))));
table[2] = std::move(table[15]);
for (auto& i : table)
{
if (i.second.get())
printf("%d\n", *i.second);
else
{
printf("empty\n");
i.second.reset(new int(12));
}
}
printf("%d\n", *table[15]);
The output is 42, empty, 12 - so apparently it works. As far as I can tell, the only 'problem' is that awful looking insert command. 'emplace' isn't implemented in gcc 4.6.0
输出是 42,空,12 - 显然它有效。据我所知,唯一的“问题”是那个看起来很糟糕的插入命令。'emplace' 未在 gcc 4.6.0 中实现
回答by M.H.
Try using emplace
method of map.
尝试使用emplace
地图的方法。