简体   繁体   中英

Pass std::tuple with variadic template parameter as its elements type to another function as a list of parameters

I have been implementing my version of std::map to get more understanding of how things work from the inside. While implementing std::map::emplace() , I have ran into a problem.

So, my function signature looks like this:

template <typename Key, typename Value>
template <typename ... Args1, typename ... Args2>
std::pair<typename Map<Key, Value>::Iterator, bool> Map<Key, Value>::emplace(
    std::piecewise_construct_t pwc,
    std::tuple<Args1...> first_args,
    std::tuple<Args2...> second_args);

Before actual emplacing, I do need to construct the key from first_args in order to compare keys in the tree. I have tried a few things, but cannot figure out the correct way to do this. As I understand, it should look something like this:

Key k(std::get<sizeof...(Args1)>(std::forward<Args1>(first_args));

Problem is that, for each element of the tuple, std::get() should receive a different number as its template parameter (so that the correct element of the tuple would be passed in the correct place).

I've seen people solve this problem by having size as template parameter and passing std::index_sequence as one of parameters, but std::map::emplace() does not have any of this approach, so there should be a way to do implement emplacing without this.

Thank you in advance. Any advice will be appreciated!

I've seen people solve this problem by having size as template parameter and passing std::index_sequence as one of parameters, but std::map::emplace() does not have any of this approach, so there should be a way to do implement emplacing without this.

It's true that std::map::emplace() do not receive a std::index_sequence , but I don't know if, internally, create a std::index_sequence and call an helper function to correctly manage the tuple.

In other words, you can write something as follows

Key k { make_object_from_tuple<Key>(first_arg, std::index_sequence_for<Args1...>{}) };

and inside make_object_from_tuple() you can use the std::index_sequence to extract element from tuple and construct the Key object.

In other words: as suggested from Kerndog73, you can copy the std::make_from_tuple_impl() implementation in this page .

If you don't want develop a new function, you can use the piecewise contructor from std::pair .

Nothing force you to construct a std::pair<Key, Value> : if you want construct first a Key and, only if necessary, next the Value , you can construct before a std::pair<Key, int> and after (in the case) a std::pair<Value, int> .

I mean... you can create the Key without the Value

std::tuple<int> ti{0};

Key k { std::pair<Key, int>{std::piecewise_construct_t, first_args, ti).first };

and after, only if you need it, the Value

Value v { std::pair<Value, int>{std::piecewise_construct_t, second_args, ti).first };

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM