首页 > 解决方案 > 为什么我们需要在 C++20 中的 map emplace 中使用 piecewise_construct?

问题描述

这是关于 std::map emplace 函数的潜在重载的理论问题,该函数检测到它已通过 2 个元组,而不是 C++20 中是否存在此功能的问题。

从我在之前的问题地图中看到的 emplace 是 std::pair 问题的“受害者”。

所以这让我想知道为什么只有当我们将 2 个元组传递给 emplace(并且键/值可以从各自的元组构造)时,map emplace 没有概念/SFINAE 重载才有效。

我想到的原因:

标签: c++sfinaec++20c++-concepts

解决方案


将 std::tuple 作为构造函数参数的怪异类

对,就是这样。

如果您决定m.emplace(x, y) 自动x为元组和执行分段构造功能y,那么我将不可能构建此:

struct Key { Key(std::tuple<int, int>); bool operator<(Key const&) const; };
struct Value { Value(std::tuple<char>); };
map<Key, Value> m;
m.emplace(std::tuple(1, 2), std::tuple('3'));

我需要tuple为这两种类型提供 s ,但相反,我总是得到两个ints forKey和一个charfor Value,但这是行不通的。我必须要么添加一个额外的构造函数,Key要么不做任何安放。

现在,如果您跟进并说,好吧,m.emplace(x, y)如果piecewise_constructxy元组,并且分段构造实际上是有效的......那么,首先,这变得相当复杂。但是,如果两种结构都有效怎么办?

struct Key2 {
    Key2(std::tuple<int, int>);
    Key2(int, int);
    bool operator<(Key2 const&) const;
};
map<Key2, Value> m2;
m2.emplace(std::tuple(1, 2), std::tuple('3'));

现在这总是使用(int, int)构造函数。这是用户在这里的意图吗?

基本上,将它们分开意味着用户可以做他们需要的事情并且没有歧义。


推荐阅读