agh*_*ast 7 c++ struct stdmap emplace c++17
我有一张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});
}
Run Code Online (Sandbox Code Playgroud)
但这些选项都不起作用.
使用clang ++我得到这样的错误.(版本:clang版本5.0.1(标签/ RELEASE_501/final))
/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.
Run Code Online (Sandbox Code Playgroud)
使用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
Run Code Online (Sandbox Code Playgroud)
那么,我怎样才能有效地将数据存储到我的地图中(理想情况下,使用简单易读的代码)?
Pra*_*ian 11
你的前两次尝试
dict.try_emplace(1, 2);
dict.try_emplace(1, 1, 2);
Run Code Online (Sandbox Code Playgroud)
失败,因为你不能使用try_emplace,emplace等来初始化总从值的列表.标准分配器使用()而不是使用而不是构造类型{},当然这对于聚合来说是失败的.查看此问题的答案.
第三次尝试
dict.try_emplace(1, {1, 2});
Run Code Online (Sandbox Code Playgroud)
失败是因为braced-init-list不是表达式,并且没有类型,因此模板参数推导无法将其推断为various.
您可以try_emplace通过指定构建various实例来开始工作
dict.try_emplace(1, various{1, 2});
Run Code Online (Sandbox Code Playgroud)
或者添加适当的构造函数various,这将允许前两次尝试工作.
但是,鉴于您正在使用map包含内置类型,最简单的解决方案是使用insert而不是安装.
dict.insert({1, {1, 2}});
Run Code Online (Sandbox Code Playgroud)
在map::insert上述过载称为是std::pair<iterator,bool> insert(value_type&&),这里value_type是pair<const int, various>.嵌套的braced-init-list s value_type由重载决策规则推断over.match.list,特别是第二个项目符号
如果找不到可行的初始化列表构造函数,则再次执行重载解析,其中候选函数是类的所有构造函数,
T参数列表由初始化列表的元素组成.
该pair(T1 const&, T2 const&)构造被选中.