Как найти тип пары из итератора? - PullRequest
0 голосов
/ 28 октября 2019

Я новичок здесь, а также в шаблонном программировании. У меня есть словарь (значит, это может быть либо std::map, либо std::vector<std::pair<type1, type2>>, либо std::set<std::pair<, >> ...). Я хотел написать алгоритм, который действует как стандартные библиотечные алгоритмы, используя итераторы переданного контейнера.

Ниже приводится идея.

#include <iostream>
#include <algorithm>
#include <type_traits>
#include <vector>
#include <array>
#include <map>
#include <set>
#include <iterator>

// two different types
enum EnumA { one, two, three, four, five, six};
enum EnumB { one,      three, four,       six};

//                   TypeA TypeB
using map = std::map<EnumA, EnumB>;
           // or std::vector<std::pair<EnumA, EnumB>>
           // or std::set<std::pair<EnumA, EnumB>>
           // or std::array<std::pair<EnumA, EnumB>, 3>

const  map itemMap{       // the map
   {EnumA::one, EnumB::one}, 
   {EnumA::three, EnumB::three}, 
   {EnumA::six, EnumB::six}, 
};

template<typename Iterator, typename B>
/* type of KEY(first) of the map/container from the iterator???*/ AfromB(Iterator begin, Iterator end, B bObj)
{
   // static_assert(begin != end); // container should not be empty!
   using Type = typename std::iterator_traits<Iterator>::value_type;
   using AType = decltype( /* how to find the type of KEY(first) of the map/container? */);
   using BType = decltype(/* how to find the type of VALUE(second) of the map/container? */);

   auto iter = std::find_if(begin, end, [bObj](const Type& entry) { return entry.second == bObj;});
   return iter != end ? iter->first: begin->first; // if not found return the first element match
}
// will do BfromA(Iterator begin, Iterator end, B bObj) similarly afterwards

int main()
{
   EnumA aEnum = AfromB(itemMap.cbegin(), itemMap.cend(), EnumB::six);  // I can use it like
}

Там вы можете видеть в коде, я не знаю, как найти тип ключа / первого и значения / второго пары в словаре. После поиска в Google я обнаружил, что могу найти тип пары ключ-значение по

using Type = typename std::iterator_traits<Iterator>::value_type;

, но не для лиц этой пары. Можно ли найти? Я использую C ++ 11.

Извините за плохой английский. Спасибо за помощь.

1 Ответ

5 голосов
/ 28 октября 2019

У вас уже есть тип значения карты:

using Type = typename std::iterator_traits<Iterator>::value_type;

Тип значения карты: std::pair<first_type,second_type>, и для получения пар первого и второго типа вы можете использовать его first_type и second_type:

using key_type = typename Type::first_type;
using mapped_type = typename Type::second_type;

Чтобы использовать key_type в качестве типа возврата, я бы, вероятно, использовал небольшой помощник:

template <typename Iterator>
struct KeyAndMappedType {
    using value_type = typename std::iterator_traits<Iterator>::value_type;
    using const_key_type = typename value_type::first_type;
    using key_type = typename std::remove_const<const_key_type>::type;
    using mapped_type = typename value_type::second_type;
};

, а затем

template <typename Iterator, typename B>
typename KeyAndMappedType<Iterator>::key_type AfromB(Iterator begin, Iterator end, B bObj) {
    ...
}

Обратите внимание, что карты key_type всегда const. Так как иногда вам нужен этот тип также как неконстантный, я решил, что мой KeyAndMapType должен обеспечивать и то и другое (возможно, имена должны были быть обратными, то есть key_type как const и non_const_key_type, но я оставлю эторешать вам детали).

...