如何在标准::映射中try_emplace POD 结构?
How can I try_emplace a POD struct in a std::map?
我有一张需要存储int -> { basic types }
的地图。
我想简单地创建一个struct { int f1, int f2; };
并直接存储值,在存储过程中就地构建结构。我不希望有任何重复的键,所以try_emplace
似乎是理想的。
我写了这段代码:
// mcve.cpp
#include <map>
#include <string>
struct various { int f1, f2; };
using map_t = std::map<int, various>;
void
example()
{
map_t dict;
//dict.try_emplace(1, 2);
dict.try_emplace(1, 1, 2);
//dict.try_emplace(1, {1, 2});
}
但这些选项都不起作用。
使用 clang++ 我收到这样的错误。(版本:clang 版本 5.0.1 (标签/RELEASE_501/最终版))
/opt/local/libexec/llvm-5.0/include/c++/v1/tuple:1365:7: error: no matching
constructor for initialization of 'various'
second(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...)
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
### ... many lines ...
mcve.cpp:14:7: note: in instantiation of function template specialization
'std::__1::map<int, various, std::__1::less<int>,
std::__1::allocator<std::__1::pair<const int, various> > >::try_emplace<int,
int>' requested here
dict.try_emplace(1, 1, 2);
^
mcve.cpp:4:8: note: candidate constructor (the implicit copy constructor) not
viable: requires 1 argument, but 2 were provided
struct various { int f1, f2; };
^
mcve.cpp:4:8: note: candidate constructor (the implicit move constructor) not
viable: requires 1 argument, but 2 were provided
mcve.cpp:4:8: note: candidate constructor (the implicit default constructor) not
viable: requires 0 arguments, but 2 were provided
1 error generated.
使用 g++ 我得到这样的错误。(版本: g++ (MacPorts gcc7 7.2.0_0) 7.2.0):
In file included from /opt/local/include/gcc7/c++/bits/node_handle.h:40:0,
from /opt/local/include/gcc7/c++/bits/stl_tree.h:72,
from /opt/local/include/gcc7/c++/map:60,
from mcve.cpp:1:
/opt/local/include/gcc7/c++/tuple: In instantiation of 'std::pair<_T1, _T2>::pair(std::tuple<_Args1 ...>&, std::tuple<_Args2 ...>&, std::_Index_tuple<_Indexes1 ...>, std::_Index_tuple<_Indexes2 ...>) [with _Args1 = {int&&}; long unsigned int ..._Indexes1 = {0}; _Args2 = {int&&, int&&}; long unsigned int ..._Indexes2 = {0, 1}; _T1 = const int; _T2 = various]':
### ... many lines ...
mcve.cpp:14:26: required from here
/opt/local/include/gcc7/c++/tuple:1652:70: error: no matching function for call to 'various::various(int, int)'
second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
^
mcve.cpp:4:8: note: candidate: various::various()
struct various { int f1, f2; };
^~~~~~~
mcve.cpp:4:8: note: candidate expects 0 arguments, 2 provided
mcve.cpp:4:8: note: candidate: constexpr various::various(const various&)
mcve.cpp:4:8: note: candidate expects 1 argument, 2 provided
mcve.cpp:4:8: note: candidate: constexpr various::various(various&&)
mcve.cpp:4:8: note: candidate expects 1 argument, 2 provided
那么,如何有效地将数据存储到我的地图中(理想情况下,使用简单易读的代码)?
你的前两次尝试
dict.try_emplace(1, 2);
dict.try_emplace(1, 1, 2);
失败,因为不能使用try_emplace
、emplace
等从值列表初始化聚合。标准分配器使用()
而不是{}
就地构造类型,这当然会失败。请参阅此问题的答案。
第三次尝试
dict.try_emplace(1, {1, 2});
失败是因为大括号初始化列表不是表达式,并且没有类型,因此模板参数推导无法将其推断为various
。
您可以通过指定要构造various
实例来获取try_emplace
工作
dict.try_emplace(1, various{1, 2});
或者向various
添加适当的构造函数,这将允许前两次尝试工作。
但是,鉴于您使用的是包含内置类型的map
,最简单的解决方案是仅使用insert
而不是放置。
dict.insert({1, {1, 2}});
上面所说的map::insert
重载是std::pair<iterator,bool> insert(value_type&&)
,其中value_type
是pair<const int, various>
。嵌套的大括号初始化列表s 被推导出为value_type
over.match.list
中的重载解析规则,特别是第二个项目符号
如果未找到可行的初始值设定项列表构造函数,则再次执行重载解析,其中候选函数是类
T
的所有构造函数,参数列表由初始值设定项列表的元素组成。
pair(T1 const&, T2 const&)
构造函数处于选中状态。
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- TMap::Emplace() 在应用现有密钥时会覆盖吗?
- 为什么 C++ std::unordered_map 从 emplace/ 找到返回一个迭代器?
- 如何在 malloc 内存中初始化非 POD 数据
- 使用 std::index_sequence 初始化具有固定大小数组成员的 POD 结构容器
- 将 std::map::emplace 与返回 shared_ptr 的函数一起使用是否正确?
- Qt5 远程对象 + 自定义类型,但不在 POD 中
- 带有 char[] 字段的 POD 结构的 constexpr 构造
- 非 POD 的零初始化
- C++定义构造函数使对象成为非 POD
- 是否可以使用 std::array 作为 POD 结构的数据容器?
- 指向 POD 类型的指针之间的静态转换与重新解释转换
- 具有非 POD 对象的 GLib 异步队列
- 约束类模板函数以接受特定的 POD 类型
- 从基本类型转换为非 POD 结构
- 我可以说服自动生成的构造函数将我的 POD 类成员归零吗?
- 根据 MSVC,具有易失性成员的结构不再是 POD
- 不为 emplace() 定义构造函数的解决方法
- 如何提取由 unordered_map::emplace 重新调整的货币对的值?
- 快速将无符号字符的向量强制转换为POD结构的向量,反之亦然