Использование std :: tm в качестве ключа в std :: map - PullRequest
5 голосов
/ 12 мая 2011

Я бы хотел использовать std :: tm () в качестве ключа для контейнера std :: map. Но когда я пытаюсь его скомпилировать, я получаю много (10) ошибок.

Например:

1

ошибка C2784: 'bool std :: operator <(Const станд :: basic_string <_Elem, _Traits, _Alloc> &, const _Elem *) ': не смог вывести шаблонный аргумент для 'const станд :: basic_string <_Elem, _Traits, _Alloc> & 'from' const tm 'c: \ программные файлы (x86) \ Microsoft Visual Studio 10.0 \ vc \ include \ xfunctional 125

2

ошибка C2784: 'bool std :: operator <(const _Elem *, const станд :: basic_string <_Elem, _Traits, _Alloc> &) ': не удалось вывести шаблон аргумент для 'const _Elem *' из 'const tm' c: \ программные файлы (x86) \ Microsoft Visual Studio 10,0 \ vc \ include \ xfunctional 125

3.

ошибка C2784: 'bool std :: operator <(const std :: vector <_Ty, _Ax> &, const std :: vector <_Ty, _Ax> &) ': не удалось вывести аргумент шаблона для 'const std :: vector <_Ty, _Ax> & 'from' const tm 'c: \ program files (x86) \ microsoft визуальная студия 10.0 \ vc \ include \ xfunctional 125

Означает ли все это, что я "просто" должен создать функциональный объект, который сравнивает два std :: tm, потому что для этого не определено стандартное сравнение? Или есть еще одна хитрость? (или это вообще невозможно для меня? ^^)

Код:

#include <map>
#include <ctime>
#include <string>


int main()
{
    std::map<std::tm, std::string> mapItem;
    std::tm TM;

    mapItem[TM] = std::string("test");
    return 0;
};

Ответы [ 4 ]

8 голосов
/ 12 мая 2011

std::map использует компаратор, чтобы проверить, существует ли ключ или нет. Поэтому, когда вы используете std::tm, вы должны предоставить компаратор в качестве третьего аргумента.

template < class Key, class T, class Compare = less<Key>,
           class Allocator = allocator<pair<const Key,T> > > class map

Таким образом, решение будет функтором (как вы уже догадались):

struct tm_comparer
{
   bool operator () (const std::tm & t1, const std::tm & t2) const
   {           //^^ note this

        //compare t1 and t2, and return true/false
   }
};

std::map<std::tm, std::string, tm_comparer> mapItem;
                             //^^^^^^^^^^ pass the comparer!

Или определить свободную функцию (operator <) как:

bool operator < (const std::tm & t1, const std::tm & t2)
{          // ^ note this. Now its less than operator

    //compare t1 and t2, and return true/false
};

std::map<std::tm, std::string> mapItem; //no need to pass any argument now!
2 голосов
/ 12 мая 2011

Да, вам нужно определить оператор <для структуры tm.см. например <a href="http://www.cplusplus.com/reference/stl/map/map/" rel="nofollow">http://www.cplusplus.com/reference/stl/map/map/ (внизу страницы).

2 голосов
/ 12 мая 2011

Достаточно свободной функции, вам не нужен объект функции.

2 голосов
/ 12 мая 2011

Да std::tm не определяет оператор <.

...