Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> пользовательский класс в multimap, user defined, multimap 
V
    Опции темы
Hohhi
Дата 24.4.2010, 12:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 171
Регистрация: 25.2.2006
Где: Молдова

Репутация: нет
Всего: нет



Доброго дня! Хочу научиться пользоваться пользовательскими классами в multimap. В качестве примера я буду использовать класс Time. В качестве ассоциации временные пояса, то есть ключевому времени  будут соответствовать значения городов. Пишу с использованием VS 2008. Приведу пользовательский класс:
Код

#pragma once
#include "stdafx.h"
using namespace std;
class Time
{
    private:
        int hours;
        int minutes;
        int seconds;
    public:
        Time();
        Time(int h,int m, int s);
        Time(const Time& t);
        Time(long sec);
        Time& operator++();
        Time operator++(int);
        Time& operator--();
        Time operator--(int);
        int operator==(Time& t);
        friend ostream& operator<< (ostream& o, Time& t);
        friend Time operator+(Time& t1,Time& t2);
        friend Time operator-(Time& t1,Time& t2);
        ~Time(){};
};



А вот попытка его использовать:
Код

// map_insert_find_end.cpp
// compile with: /EHsc
#pragma warning(disable:4786)
#include "stdafx.h"
#include <iostream>
#include <string>
#include <map>
#include "Time.h"
using namespace std;
typedef multimap < Time, string > multiTime;


void printMap(multiTime map)
{
   multiTime ::iterator iter;
   Time tmp;
   iter = map.begin ();
   tmp=-30000;
   for (; iter != map.end (); iter++)
   {
       Time now=(*iter).first;
       if (tmp==now)
         cout <<", "<<(*iter).second;   
       else
       {
        tmp=(*iter).first;
        cout<<endl<<tmp<<" is translated "<<(*iter).second;
       }
   }
}

void replace_value(multiTime& map, Time& key, string newValue)
{
   multiTime ::iterator iter = map.find(key);
   (*iter).second=newValue;
}
void remove (multiTime& map, int from, int quantity)
{
    multiTime ::iterator iter=map.begin();
    int tmp=0;
    while(++tmp<from) iter++;
    tmp=0;
    while(tmp++<quantity)
        map.erase(iter++);
}
void copyMapTo(multiTime& map,multiTime map2)
{
    multiTime ::iterator iter=map2.begin();
    while (iter!=map2.end())
    {
        map.insert(multiTime::value_type( (*iter).first, (*iter).second));
        iter++;
    }
}
void wait()
{
   cout << endl;
   int a;
   cin>>a;
}

int main( )
{
   multiTime map;
   multiTime ::iterator iter2;
   multiTime ::iterator iter;
   map.insert( multiTime::value_type( Time(120), "Chisinau" ) );
   map.insert( multiTime::value_type( Time(180), "Moscow" ) );
   map.insert( multiTime::value_type( Time(120), "Kyev" ) );
   map.insert( multiTime::value_type( Time(0), "London" ) );
   map.insert( multiTime::value_type( Time(60), "Paris" ) );
   map.insert( multiTime::value_type( Time(60), "Rome" ) );
   map.insert( multiTime::value_type( Time(240), "Kazan" ) );
   map.insert( multiTime::value_type( Time(720), "Wellington" ) );
   map.insert( multiTime::value_type( Time(120), "Athens" ) );
   printMap(map);
   map.erase(++(++(++map.begin())),--(--map.end()));
   replace_value(map,Time(120),"Minsk");
   cout<<endl;
   printMap(map);
   multiTime map2;
   map2.insert(multiTime::value_type(Time(120),"Bucharest"));
   map2.insert(multiTime::value_type(Time(120),"Stambul"));
   map2.insert(multiTime::value_type(Time(240),"Tbilisi"));
   map2.insert(multiTime::value_type(Time(240),"Yerevan"));
   map2.insert(multiTime::value_type(Time(60),"Amstardam"));
   map2.insert(multiTime::value_type(Time(60),"Berlin"));
   remove (map,3,2);
   cout<<endl;
   printMap(map);
   copyMapTo(map,map2);
   cout<<endl<<endl<<"------------map----------------"<<endl;
   printMap(map);
   cout<<endl<<endl<<"------------map2----------------"<<endl;
   printMap(map2);
   wait();
}


В результате исполения выдаются ошибки в 143 строке файла fucntional, а именно:
Код

template<class _Ty>
    struct less
        : public binary_function<_Ty, _Ty, bool>
    {    // functor for operator<
    bool operator()(const _Ty& _Left, const _Ty& _Right) const
        {    // apply operator< to operands
        return (_Left < _Right);
        }
    };


Работаю с STL впервые. Пытался комментить прогу построчно, понять, что не так. Но так и не понял...
PM MAIL ICQ   Вверх
GoldFinch
Дата 24.4.2010, 12:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 15
Всего: 26



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

Добавлено через 1 минуту и 24 секунды
и заодно текст ошибки, и стек вызовов, если ошибка в рантайме
PM MAIL ICQ   Вверх
Hohhi
Дата 24.4.2010, 13:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 171
Регистрация: 25.2.2006
Где: Молдова

Репутация: нет
Всего: нет



привожу минимальный код:
Код


#pragma warning(disable:4786)
#include "stdafx.h"
#include <iostream>
#include <string>
#include <map>
#include "Time.h"
using namespace std;
typedef multimap < Time, string > multiTime;


void printMap(multiTime map)
{
   multiTime ::iterator iter;
   Time tmp;
   iter = map.begin ();
   tmp=-30000;
   for (; iter != map.end (); iter++)
   {
       Time now=(*iter).first;
       if (tmp==now)
         cout <<", "<<(*iter).second;   
       else
       {
        tmp=(*iter).first;
        cout<<endl<<tmp<<" is translated "<<(*iter).second;
       }
   }
}

void wait()
{
   cout << endl;
   int a;
   cin>>a;
}

int main( )
{
   multiTime map;
   multiTime ::iterator iter2;
   multiTime ::iterator iter;
   map.insert( multiTime::value_type( Time(120), "Chisinau" ) );
   map.insert( multiTime::value_type( Time(180), "Moscow" ) );
   map.insert( multiTime::value_type( Time(120), "Kyev" ) );
   map.insert( multiTime::value_type( Time(0), "London" ) );
   map.insert( multiTime::value_type( Time(60), "Paris" ) );
   map.insert( multiTime::value_type( Time(60), "Rome" ) );
   map.insert( multiTime::value_type( Time(240), "Kazan" ) );
   map.insert( multiTime::value_type( Time(720), "Wellington" ) );
   map.insert( multiTime::value_type( Time(120), "Athens" ) );
   printMap(map);
   wait();
}

Привожу ошибки:
Error    1    error C2784: 'bool std::operator <(const std::_Tree<_Traits> &,const std::_Tree<_Traits> &)' : could not deduce template argument for 'const std::_Tree<_Traits> &' from 'const Time'    c:\program files\microsoft visual studio 9.0\vc\include\functional    143    lab32
Error    2    error C2784: 'bool std::operator <(const std::basic_string<_Elem,_Traits,_Alloc> &,const _Elem *)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'const Time'    c:\program files\microsoft visual studio 9.0\vc\include\functional    143    lab32
Error    3    error C2784: 'bool std::operator <(const _Elem *,const std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'const _Elem *' from 'const Time'    c:\program files\microsoft visual studio 9.0\vc\include\functional    143    lab32
Error    4    error C2784: 'bool std::operator <(const std::basic_string<_Elem,_Traits,_Alloc> &,const std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'const Time'    c:\program files\microsoft visual studio 9.0\vc\include\functional    143    lab32
Error    5    error C2784: 'bool std::operator <(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)' : could not deduce template argument for 'const std::reverse_iterator<_RanIt> &' from 'const Time'    c:\program files\microsoft visual studio 9.0\vc\include\functional    143    lab32
Error    6    error C2784: 'bool std::operator <(const std::_Revranit<_RanIt,_Base> &,const std::_Revranit<_RanIt2,_Base2> &)' : could not deduce template argument for 'const std::_Revranit<_RanIt,_Base> &' from 'const Time'    c:\program files\microsoft visual studio 9.0\vc\include\functional    143    lab32
Error    7    error C2784: 'bool std::operator <(const std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)' : could not deduce template argument for 'const std::pair<_Ty1,_Ty2> &' from 'const Time'    c:\program files\microsoft visual studio 9.0\vc\include\functional    143    lab32
Error    8    error C2676: binary '<' : 'const Time' does not define this operator or a conversion to a type acceptable to the predefined operator    c:\program files\microsoft visual studio 9.0\vc\include\functional    143    lab32


PM MAIL ICQ   Вверх
GoldFinch
Дата 24.4.2010, 14:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 15
Всего: 26



Hohhi, у вашего класса Time нет операторов сравнения
PM MAIL ICQ   Вверх
borisbn
Дата 24.4.2010, 14:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



В описании ошибки, выдываемой компилятором, всё чётко сказано: не хватает оператора меньше для класса Time. В multimap можно добавлять классы с определённым оператором меньше.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Hohhi
Дата 24.4.2010, 14:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 171
Регистрация: 25.2.2006
Где: Молдова

Репутация: нет
Всего: нет



borisbn, 
GoldFinch, спасибо, просто я эти операторы непосредственно в своём коде не использовал. Это необходимо для правильной работы итераторов?

Добавлено через 5 минут и 21 секунду
Подкорректировал код, всё замечательно работает, спасибо за оперативную помощь.

Помогите только разобраться с причиной необходимости оператора <.
PM MAIL ICQ   Вверх
GoldFinch
Дата 24.4.2010, 14:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 15
Всего: 26



Hohhi, multimap'у нужна поддержка операции "<" для сравнения ключей
Цитата

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

# Key: Type of the key values. Each element in a multimap  is generally identified by its key value, although multiple elements can have the same key value.
# T: Type of the mapped value. Each element in a multimap is used to store some data as its mapped value.
# Compare: Comparison class: A class that takes two arguments of the key type and returns a bool.
The expression comp(a,b), where comp is an object of this comparison class and a and b are key values,
shall return true if a is to be placed at an earlier position than b in a strict weak ordering operation.
This can either be a class implementing a function call operator or a pointer to a function (see constructor for an example).
This defaults to less<Key>, which returns the same as applying the less-than operator (a<b).
The multimap object uses this expression to determine the position of the elements in the container.
All elements in a multimap container are ordered following this rule at all times.


т.е. можно задать свой класс для сравнения, по умолчанию используется std::less который использует operator<

Это сообщение отредактировал(а) GoldFinch - 24.4.2010, 15:02
PM MAIL ICQ   Вверх
Hohhi
Дата 24.4.2010, 15:04 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 171
Регистрация: 25.2.2006
Где: Молдова

Репутация: нет
Всего: нет



Ясно, вот ключевое пояснение:
The multimap object uses this expression to determine the position of the elements in the container.
All elements in a multimap container are ordered following this rule at all times.

Спасибо большое
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1767 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.