Функция шаблона для max_element на картах должна знать оба типа - PullRequest
1 голос
/ 18 августа 2011

Я пытаюсь написать собственную функцию cmp для карты, простую, которая выполняет сравнение со вторым элементом карты.Я хотел бы иметь функцию в качестве шаблона, но я не могу понять, как передать типы .first и .second карты в мою функцию cmp.Мой нерабочий код приведен ниже, и он явно потерпит неудачу, поскольку типы T1 и T2 не передаются:

#include <map>
#include <vector>
#include <algorithm>

template<class T1, class T2>
bool pairCompare(const std::pair<T1,T2> & x,
                 const std::pair<T1,T2> & y) {
  return x.second < y.second; 
}

template<class T1>
typename T1::iterator map_max_element(const T1 & A) {

  // How do I pass the type to pairCompare?
  return std::max_element(A.begin(), A.end(), pairCompare<?????>);
}

int main() {
  std::map<std::vector<double>, int> A;
  map_max_element(A);

  return 0;
}

Ответы [ 3 ]

12 голосов
/ 18 августа 2011

std::map имеет вложенный тип, называемый value_type, который на самом деле является typedef, равным std::pair<const K, V>std::pair имеет два вложенных типа first_type и second_type.Используйте эту информацию как:

template<class T>
typename T::const_iterator map_max_element(const T & A) 
{
   typedef typename T::value_type pair_type;
   typedef typename pair_type::first_type K;
   typedef typename pair_type::second_type V;
   return std::max_element(A.begin(), A.end(), pairCompare<K,V>);
}

Обратите внимание, что в вашем коде неверный тип возврата.Это должно быть const_iterator, а не iterator, потому что в функции A есть const map.Отсюда вы можете получить const_iterator.: -)


Или вы можете просто написать функцию сравнения как:

template<class T>
bool pairCompare(const T & x, const T & y) {
  return x.second < y.second; 
}

И использовать ее как:

return std::max_element(A.begin(), A.end(), pairCompare<typename T::value_type>);
2 голосов
/ 20 августа 2011

Имея тот же вопрос, что и постер. Я попробовал предложенный ответ. Прекрасно работает с небольшими изменениями.

Это последний код, который работает с небольшим примером для тестирования.

#include <iostream>
#include <map>

using namespace std;

template<class T>
bool pairCompare(const T & x, const T & y)
{
  return x.second < y.second;
}

template<class T>
typename T::const_iterator map_max_element(const T &A)
{
    typedef typename T::value_type pair_type;
    return max_element(A.begin(), A.end(), pairCompare<typename T::value_type>);
}

int main()
{
    map<float, int> A;
    map<float, int>::const_iterator it;
    // Data insert

    A.insert ( pair<float, int>( -2, 1) );
    A.insert ( pair<float, int>( 0, 5) );
    A.insert ( pair<float, int>( 2, -5) );

    it = map_max_element(A);

    cout << "Row with maximum second element of a Map: " << (*it).first << " , " << (*it).second << endl;

    return 0;
}

Наслаждайтесь кодом и спасибо за эту замечательную работу, Наван.

2 голосов
/ 18 августа 2011

Вы можете использовать T1::key_type и T1::mapped_type, или, проще, просто T1::value_type, что эквивалентно std::pair<T1::key_type,T1::mapped_type>.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...