0

This it theoretical question about potential overload of std::map emplace function that detects that it has been passed 2 tuples, not a question if this functionality exists in C++20.

From what I saw in previous question map emplace is "victim" of std::pair's problems.

So that got me wondering why is there no concepts/SFINAE overload of map emplace that is active only when we pass 2 tuples to emplace (and key/value are constructible from respective tuples).

Reasons I thought of:

  • weirdo classes that take std::tuple as argument to constructor(potentially also they have ctor with that tuple's types expanded into normal arguments)
  • nobody thought it was worthwhile investing time in saving a bit of typing by solving one specific problem
Barry
  • 286,269
  • 29
  • 621
  • 977
NoSenseEtAl
  • 28,205
  • 28
  • 128
  • 277

1 Answers1

3

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

Yes, exactly.

If you decided that m.emplace(x, y) automatically did piecewise_construct functionality for tuples x and y, then it would be impossible for me to emplace construct this:

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'));

I need to provide tuples for both types, but instead I'd always get two ints for Key and a char for Value and that doesn't work. I would necessarily have to either add an extra constructor for Key or just not do any emplacing.

Now, if you follow up and say, okay, m.emplace(x, y) will automatically do piecewise_construct if x and y are tuples and also the piecewise construction is actually valid... then , first, that's getting fairly complicated. But also, what if both constructions are valid?

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'));

Now this always uses the (int, int) constructor. Is that what the user intended here?

Basically, having them separate means the user can do what they need and there's no ambiguity.

Barry
  • 286,269
  • 29
  • 621
  • 977
  • Great answer, but for the last part: standard could say that STL needs to static assert on ambiguity and warn user to use piecwise tag, but tbh I do not know if standard ever does this(tell the STL to detect weird use cases and notify users). – NoSenseEtAl May 12 '20 at 17:43
  • 1
    @NoSenseEtAl Keep in mind that "weirdo classes" includes `std::tuple`. `Key2` behaves exactly like `std::tuple` here. – Barry May 12 '20 at 17:51