首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在std::try_emplace中使用POD结构?

如何在std::try_emplace中使用POD结构?
EN

Stack Overflow用户
提问于 2018-01-22 22:09:54
回答 1查看 2.7K关注 0票数 8

我有一张需要储存的int -> { basic types }地图。

我想简单地创建一个struct { int f1, int f2; };并直接存储这些值,在存储期间在原位构造结构。我不期望有任何重复的键,所以try_emplace似乎是理想的。

我写了这段代码:

代码语言:javascript
复制
// 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 (标记/Release501/final))

代码语言:javascript
复制
/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):

代码语言:javascript
复制
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

那么,如何有效地将数据存储到映射中(理想情况下,使用简单、可读的代码)?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-01-22 22:43:54

你的前两次尝试

代码语言:javascript
复制
dict.try_emplace(1, 2);
dict.try_emplace(1, 1, 2);

失败,因为不能使用try_emplaceemplace等从值列表初始化聚合。标准分配器使用()而不是{}构造本地类型,当然,对于聚合来说,这将失败。见这个问题的答案。

第三次尝试

代码语言:javascript
复制
dict.try_emplace(1, {1, 2});

失败是因为大括号中的列表不是表达式,并且没有类型,因此模板参数演绎失败将其推断为various

您可以通过指定您正在构造一个try_emplace实例来使various工作

代码语言:javascript
复制
dict.try_emplace(1, various{1, 2});

或向various添加适当的构造函数,这将允许前两次尝试工作。

但是,考虑到您使用的是包含内置类型的map,最简单的解决方案是只使用insert而不是放置。

代码语言:javascript
复制
dict.insert({1, {1, 2}});

上面调用的map::insert重载是std::pair<iterator,bool> insert(value_type&&),其中value_typepair<const int, various>。嵌套_括号-init-list_s由value_type中的重载解析规则(特别是第二个符号)推导为over.match.list

如果没有找到可行的初始化程序列表构造函数,则再次执行重载解析,其中候选函数是类T的所有构造函数,参数列表由初始化程序列表的元素组成。

选择了pair(T1 const&, T2 const&)构造函数。

票数 13
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48391047

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档