为什么我们需要 piecewise_construct in map emplace in C++20?

Why do we need piecewise_construct in map emplace in C++20?

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

从我之前看到的question地图位置来看,std::pair的问题有"victim"个。

所以这让我想知道为什么没有 concepts/SFINAE 仅当我们将 2 个元组传递给 emplace 时激活的 map emplace 重载(并且 key/value 可以从相应的元组构造)。

我想到的原因:

weirdo classes that take std::tuple as argument to constructor

是的,完全正确。

如果您决定 m.emplace(x, y) 自动 为元组 xy 执行 piecewise_construct 功能,那么它将是我无法放置这个:

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,但我 总是Key 提供两个 int 和a char for Value 但这行不通。我必须为 Key 添加一个额外的构造函数,或者不做任何放置。

现在,如果你跟进说,好吧,如果 xy 是元组 并且 m.emplace(x, y) 会自动执行 piecewise_construct 分段构造实际上是有效的...然后,首先,它变得相当复杂。而且,如果两种结构都有效怎么办?

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) 构造函数。这是用户在这里的意图吗?

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