gpt4 book ai didi

c++ - 如何在 std::map 中尝试放置 POD 结构?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:15:34 24 4
gpt4 key购买 nike

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

我想简单地创建一个 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 (tags/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.

使用 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

那么,我怎样才能有效地将数据存储到我的 map 中(理想情况下,使用简单易读的代码)?

最佳答案

你的前两次尝试

dict.try_emplace(1, 2);
dict.try_emplace(1, 1, 2);

失败,因为你不能使用try_emplace , emplace等来初始化 aggregate来自值列表。标准分配器使用 () 就地构造类型而不是 {} ,这对于聚合来说当然会失败。查看 this question 的答案.

第三次尝试

dict.try_emplace(1, {1, 2});

失败是因为 braced-init-list 不是表达式,也没有类型,所以 template argument deduction fails将其推断为 various .

可以得到try_emplace通过指定您正在构建一个 various 来工作实例

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_typepair<const int, various> .嵌套的 braced-init-list 推导为 value_type通过 over.match.list 中的重载决议规则,特别是第二个项目符号

If no viable initializer-list constructor is found, overload resolution is performed again, where the candidate functions are all the constructors of the class T and the argument list consists of the elements of the initializer list.

pair(T1 const&, T2 const&)构造函数被选中。

关于c++ - 如何在 std::map 中尝试放置 POD 结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48391047/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com