используя структуру timespec в multimap, где и / или как определить оператор ‹

У меня есть унаследованный код, который выглядит примерно так. (Пожалуйста, сдержите смех ... Я ЗНАЮ, что это уродливо, даже после того, как я псевдокодифицировал его. Вот почему я пытаюсь улучшить его, и мое первое, над чем я работаю, - это голова с костью (по моему мнению) сохранение времени в виде удвоения миллисекунд с начала эпохи и использование этого времени в качестве ключа в мульти-карте). В любом случае это код «до», назовите его foo.h:

#include <vector>
#include <map>
#include <list>
#include <queue>
#include <string>
#include <time.h>
using namespace std;

#include "yasper.h"
using yasper::ptr;

class foo
{
private:
    ...
public:
    foo(...);
    virtual ~foo();
    ...
bool operator() (const ptr<foo> poFoo1, const ptr<foo> poFoo2)
    {
        ...
    }
}
...
typedef ptr<foo> fooPtr;

typedef queue<fooPtr> fooQueue;
typedef list<fooPtr> fooList;
typedef fooList *fooListPtr;

typedef multimap<double, fooPtr> fooTimeMap;

Я также знаю, что моя платформа не обеспечивает точности времени даже близко к наносекундам, но она немного лучше, чем секунды или миллисекунды. Также я попытался понять и реализовать предложения из нескольких похожих вопросов как из результатов Google, так и с этого сайта (C ++ Использование .find () со структурой в качестве ключа на карте и используя структуру как ключ на карте). Однако они немного отличаются, потому что они предназначены для их собственной новой структуры, и я пытаюсь сделать это с помощью существующей стандартной библиотечной структуры.

Итак, моя главная цель - изменить эту последнюю строку на:

typedef multimap<timespec, fooPtr> fooTimeMap;

Когда я делаю только это изменение, я получаю

В функции-члене 'bool std :: less ‹_Ty> :: operator () (const _Ty &, const _Ty &) const [with _Ty = timespec]': /.../include/cpp/xtree:895: создан из 'std :: _ Tree ‹_Traits> :: iterator std :: _ Tree ‹_Traits> :: find (const typename _Traits :: key_type &) [с _Traits = std :: _ Tmap_traits, std :: less, std :: allocator>>, true> ] '/home/.../foo.cpp:109: создан отсюда /.../include/cpp/functional:136: error: нет соответствия для' operator ‹'в' _Left‹ _Right '

Основываясь на этих и других упомянутых сообщениях, я попытался определить оператор меньше чем для времени ... например. перед закрытием} класса foo я положил

bool operator() (const timespec& lhs, const timespec& rhs)
{
    return ( lhs.tv_nsec < rhs.tv_nsec && lhs.tv_sec == rhs.tv_sec ) ||
        lhs.tv_sec < rhs.tv_sec;
}

но я думаю, я не понимаю, где это подходящее место и почему. Или даже если это не «нужное место», а где-то, что достаточно для того, чтобы multimap<timespec,...> скомпилировал (и запустил: -). Также в некоторых сообщениях говорится об определении оператора ‹(...), а в других - об операторе () (...).

Я бы предпочел не определять целый новый класс-оболочку, например timespec_compare_class, вокруг timespec (я видел синтаксис multimap<timespec, fooPtr, timespec_compare_class> в других сообщениях), поэтому я бы предпочел избежать этого, если есть способ сделать это внутри самого класса foo или даже после} foo, но все еще внутри foo.h.

(обратите внимание, я не думаю, что «bool operator () (const ptr poFoo1, const ptr poFoo2)», ни fooQueue, fooList, ни fooListPtr не имеют отношения к вопросу, но я оставил их в псевдокоде просто в случае.)

Итак, помимо «прочтите учебник по C ++», который, как я знаю, мне нужно сделать, может ли кто-нибудь указать мне на более быстрое решение?

@thb и @MarkRansom, спасибо за ответ ... да, они упоминались и в других сообщениях, хотя, как я уже сказал, несколько другие случаи, например, с их собственными новыми структурами, которые я пытался применить к моему случаю.

например 1) Когда я делаю bool operator() (const timespec& lhs, const timespec& rhs) внутри {фигурных скобок} foo, я все равно получаю «ошибка: нет совпадения для 'operator‹' в '_Left ‹_Right'»

например 2) когда я делаю это за пределами фигурных скобок, непосредственно перед typedef multimap, я получаю «bool operator () (const timespec &, const timespec &) 'must be a nonstatic member function».

например 3) Когда я делаю bool operator< (const timespec& lhs, const timespec& rhs) внутри фигурных скобок, я получаю «'bool foo :: operator‹ (const timespec &, const timespec &)' должен принимать ровно один аргумент ». И даже если я изменил это на один аргумент, я не думаю, что это то, что я хочу, потому что я не пытаюсь сказать, как сравнивать foo со спецификацией времени.

например 4) Когда я делаю это вне фигурных скобок, непосредственно перед typedef multimap, я получаю «множественное определение` operator ‹(timespec const &, timespec const &) '».

Так один из них ближе к правильному пути или что-то совершенно другое?


person Martin Moops    schedule 20.03.2012    source источник
comment
Есть ли причина, по которой вы предпочитаете не переименовывать operator () в operator ‹? Во всяком случае, я знаю два основных способа делать то, что вы хотите. Во-первых, с помощью operator ‹. Во-вторых, поочередно, путем определения подходящего функтора Less. (По моему опыту, первое обычно кажется проще.)   -  person thb    schedule 20.03.2012


Ответы (2)


Я бы немного изменил его:

struct TimeTest
{
    bool operator()(timespec const& lhs, timespec const& rhs) const
    {
         return <TEST>
    }
};
typedef multimap<timespec, fooPtr, TimeTest> fooTimeMap;

Причина, по которой я хотел бы сделать дополнительный шаг, заключается в том, что если вы определяете operator ‹для timespec, у него есть высокая вероятность конфликта с любой библиотекой C ++, которая использует информацию о времени. Они могут не определять один и тот же порядок, и тогда все усложняется.

Явно устанавливая сравнение, вы гарантируете, что столкновений не будет.

person Martin York    schedule 20.03.2012
comment
Три ура за доброту незнакомцев !! Это компилируется (со следующим за пределами класса foo {...}). Большое спасибо! struct TimeTest {bool operator () (const timespec & lhs, const timespec & rhs) const {return (lhs.tv_nsec ‹rhs.tv_nsec && lhs.tv_sec == rhs.tv_sec) || lhs.tv_sec ‹rhs.tv_sec; }; }; typedef multimap ‹timespec, fooPtr, TimeTest› fooTimeMap; - person Martin Moops; 20.03.2012
comment
Я должен сказать, что это компилируется, и я сообщу, если он также не будет хорошо протестирован! : -) - person Martin Moops; 20.03.2012

Почему бы не определить оператор «меньше» как

bool operator< (const timespec& lhs, const timespec& rhs) { ... }

что немного отличается от того, что вы написали? Вызов функции operator () () действительно можно использовать вместо operator ‹(),, но не совсем так, как вы это делали. В любом случае operator ‹(), вероятно, проще.

Удачи.

person thb    schedule 20.03.2012
comment
Верно. operator() имеет смысл только тогда, когда он является членом класса, который в этом случае будет называться функтором. - person Mark Ransom; 20.03.2012
comment
Да, я тоже пробовал это, но все еще не могу понять синтаксис правильно, поэтому я, должно быть, что-то неправильно понимаю. - person Martin Moops; 20.03.2012
comment
Проблема здесь в том, что вы потенциально можете столкнуться с оператором «меньше чем», определенным другим пакетом. Я думаю, что предоставил функтор сравнения для контейнера, а не полагался на параметры шаблона по умолчанию для сопоставления его с оператором ‹ - person Martin York; 20.03.2012