Я хочу иметь структуру token
, в которой есть пары начала / конца для информации о положении, предложении и абзаце. Я также хочу, чтобы участники были доступны двумя разными способами: в качестве начальной / конечной пары и индивидуально. Дано:
struct token {
struct start_end {
int start;
int end;
};
start_end pos;
start_end sent;
start_end para;
typedef start_end token::*start_end_ptr;
};
Я могу написать функцию, скажем distance()
, которая вычисляет расстояние между любой из трех пар start
/ end
, например:
int distance( token const &i, token const &j, token::start_end_ptr mbr ) {
return (j.*mbr).start - (i.*mbr).end;
}
и назовите это как:
token i, j;
int d = distance( i, j, &token::pos );
, который вернет расстояние пары pos
. Но я также могу передать &token::sent
или &token::para
, и он делает то, что я хочу. Следовательно, функция является гибкой.
Однако теперь я также хочу написать функцию, скажем, max()
, которая вычисляет максимальное значение всех pos.start
или всех pos.end
или всех sent.start
и т. Д.
Если я добавлю:
typedef int token::start_end::*int_ptr;
Я могу написать функцию как:
int max( list<token> const &l, token::int_ptr p ) {
int m = numeric_limits<int>::min();
for ( list<token>::const_iterator i = l.begin(); i != l.end(); ++i ) {
int n = (*i).pos.*p; // NOT WHAT I WANT: It hard-codes 'pos'
if ( n > m )
m = n;
}
return m;
}
и назовите это как:
list<token> l;
l.push_back( i );
l.push_back( j );
int m = max( l, &token::start_end::start );
Однако, как указано в комментарии выше, я не хочу жестко кодировать pos
. Мне нужна гибкость доступа к start
или end
любого из pos
, sent
или para
, которые будут переданы в качестве параметра max()
.
Я пробовал несколько вещей, чтобы заставить это работать (пытался использовать союзы, анонимные союзы и т. Д.), Но я не могу придумать структуру данных, которая обеспечивает гибкость в обоих направлениях, сохраняя каждое значение только один раз.
Есть идеи, как организовать структуру token
, чтобы я мог получить то, что хочу?
Попытка разъяснения
Учитывая структуру пар целых чисел, я хочу иметь возможность "разрезать" данные двумя различными способами:
- Путем передачи указателя на член конкретной пары начало / конец, чтобы вызываемая функция работала с любой парой, не зная, какая пара. Вызывающий абонент решает, какая пара.
- Передав указатель на член определенной
int
(т. Е. Только один int
любой пары), чтобы вызываемая функция работала с любым int
, не зная, какой int
или какая пара сказала, что int
от. Вызывающий абонент решает, какая int
из какой пары.
Другим примером для последнего будет суммировать, скажем, все para.end
или все sent.start
.
Кроме того, и это важно: для # 2 выше, в идеале, я бы хотел передать только один указатель на член, чтобы уменьшить нагрузку на вызывающего. Поэтому я пытаюсь что-то выяснить, используя союзы.
Для # 2 структура будет оптимально выстроена следующим образом:
struct token2 {
int pos_start;
int pos_end;
int sent_start;
int sent_end;
int para_start;
int para_end;
};
Хитрость заключается в том, чтобы token
и token2
как-то перекрывались с union
, но неясно, можно ли / как это сделать, и при этом удовлетворить доступные требования.