Карта STL для структуры, определенной в ANSI C - PullRequest
0 голосов
/ 20 апреля 2011

Я пишу код в смешанной среде C / C ++.У меня есть структура в части C, и я хотел бы собрать ее в контейнер карты в части C ++.Я думаю, что я должен определить пользовательский key_compare функциональный объект и позволить STL map :: insert () упорядочивать узлы.Однако я не знаю, как я могу изменить контейнер карты для настройки функции map :: find () .Я ищу способ настроить функцию map :: find () , чтобы сделать нечто большее, чем функция key_compare для проверки эквивалентности.

Пожалуйста, дайте мне знать, как я могу поместить эти функции в STL :: map или STL :: set?

вот моя структура в C-части (скомпилировано с gcc):

typedef struct  iotrace_arh_node 
{
    double time;
    unsigned long long int blkno;
    int bcount;
    u_int flags;
    int devno; 
    unsigned long stack_no;
} iotrace_arh_node_t;

вот моя предложенная key_compare и функция проверки эквивалентности для find () в части C ++ (скомпилировать с g ++):

int key_compare ( struct iotrace_arh_node tempa, struct iotrace_arh_node tempb )
{
return (tempa.blkno-tempb.blkno);
}


int key_equal( struct iotrace_arh_node tempa, struct iotrace_arh_node tempb )
{
    if( (tempa.blkno == tempb.blkno) && (tempa.bcount == tempb.bcount) )
        return 0; // tempa and tempb is equal, node fund in the map
    else if ( (tempb.blkno < tempa.blkno)  )
        return -1;  //tempb is less than tempa
    else if ( (tempb.blkno >= tempa.blkno) && ( tempb.blkno + tempb.bcount < tempa.blkno + tempa.bcount) )      
        return 0; // tempa and tempb is equal, node fund in the map
    else
        return 1;  //tempb is grater than tempa
}

Ответы [ 3 ]

2 голосов
/ 20 апреля 2011

Чтобы использовать тип в качестве ключа на карте или в наборе, необходимо обеспечить сравнение «меньше», которое принимает два аргумента и возвращает true, если первое должно предшествовать второму. Самый простой способ использовать его в наборе - определить его как функциональный объект:

struct key_compare {
    bool operator()(const iotrace_arh_node & a, const iotrace_arh_node & b) {
        return a.blkno < b.blkno;
    }
};

и используйте его в качестве аргумента шаблона "компаратора" на карте или установите:

typedef std::set<iotrace_arh_node, key_compare> node_set;

Если вам нужны разные способы сравнения ключей, вы можете создавать разные наборы с разными компараторами. Тем не менее, вы не можете изменить компаратор после создания набора; объекты в наборе хранятся в соответствии с порядком, определенным компаратором, поэтому его изменение сделает набор непригодным для использования. Если вам нужно искать один и тот же набор по разным полям, взгляните на Boost.MultiIndex

Вам не нужно предоставлять сравнение на равенство.

2 голосов
/ 20 апреля 2011

Стандартные функции сравнения различаются в C и C ++. В C, как вы написали, вы возвращаете -1, 0 или 1, когда первый аргумент меньше, равен или больше второго. Но в C ++ вы должны либо перегрузить оператор <, либо написать функцию сравнения, которая выполняет ту же функцию, что и оператор <, и присваивает свое имя функциям STL. Но вы должны убедиться, что ваш <должен быть транзитивным (т.е. <code>a<b && b<c => a<c). Это означает, что ваша функция key_compare должна выглядеть так:

bool key_compare ( const struct iotrace_arh_node& tempa, const struct iotrace_arh_node& tempb )
{
return (tempa.blkno < tempb.blkno);
}

Нет необходимости определять key_equal, потому что (k1 == k2) <=> (!(k1<k2)&&!(k2<k1)). И AFAIK вы не можете использовать различные функции сравнения, когда вы вставляете и находите.

1 голос
/ 20 апреля 2011

Для сравнения смотрите здесь: Карта STL с пользовательским объектом функции сравнения

struct my_comparer
{
   bool operator() ( const struct iotrace_arh_node& left, const struct iotrace_arh_node& right )
   {
      return left.blkno < rigth.blkno);
   }

}

Компаратор должен быть двоичным предикатом, а не простой функцией.

Тогда вы можете использовать его на карте:

std::map<Key, Data, Compare, Alloc>

(см. Здесь: http://www.cplusplus.com/reference/stl/map/)

Для сравнения и выделения есть значения по умолчанию.

Какой у вас ключ, кстати?

НТН

Mario

...