std::map of tuple to tuple and using emplace

Viewed 3805

Consider the following code, compiled with g++ 7.0.1 (-std=c++17):

#include <map>
#include <tuple>

int main()
{
    // Create an alias for a tuple of three ints
    using ThreeTuple=std::tuple<int,int,int>;
    // Create an alias for a map of tuple to tuple (of three ints)
    using MapThreeTupleToThreeTuple=std::map<ThreeTuple,ThreeTuple>;

    MapThreeTupleToThreeTuple m;

    // The following does NOT compile
    m.emplace({1,2,3},{4,5,6});

    // ..., and neither does this
    m.emplace(std::piecewise_construct,{1,2,3},{4,5,6});
}

I would have thought that the initializer_list arguments to map::emplace() would have sufficed and would have resulted in the insertion of the tuple key to tuple value association as specified. Apparently, the compiler disagrees.

Of course creating a tuple explicitly (i.e., ThreeTuple{1,2,3} instead of just {1,2,3}) and passing that to map::emplace() solves the problem, but why can't the initializer lists be passed directly to map::emplace() which would automatically forward them to the tuple constructors?

3 Answers

Something like that would work in C++17:

m.try_emplace({1,2,3},4,5,6);
Related