Macro замещающий текст не является решением вашей проблемы, так как индекс i
известен только во время выполнения. Макросы обрабатываются до начала компиляции.
Если N
не известно во время компиляции, вам нужно будет использовать некоторую комбинацию условных структур и, возможно, петлю. Если число KeyClass*
эс фиксированы (который, кажется, так), вы можете быть в состоянии сделать что-то вроде этого:
void Foo(int N, Array& array, const Bar& arg)
{
if(N > 3 || N <= 0) return;
Data* data = array[0]->find(KeyClassA(arg.fieldA));
// DoSomething(data);
if(N == 1) return;
data = array[1]->find(KeyClassB(arg.fieldB));
// DoSomething(data);
if(N == 2) return;
data = array[2]->find(KeyClassC(arg.fieldC));
// DoSomething(data);
}
Поместить все общий код в функции DoSomething()
(предпочтительно с использованием лучшего имени функции), поэтому вы не повторяетесь для всех возможных допустимых значений для N
.
Если N
известно во время компиляции, вы можете просто развернуть цикл.
void Foo(Array& array, const Bar& arg)
{
Data* data = array[0]->find(KeyClassA(arg.fieldA));
// DoSomething(data);
data = array[1]->find(KeyClassB(arg.fieldB));
// DoSomething(data);
data = array[2]->find(KeyClassC(arg.fieldC));
// DoSomething(data);
}
Вы даже можете получить фантазии с шаблоном метапрограммированием, если вы много, а не раскатывать Петля себя, хотя это может быть излишним за то, что вы делаете:
// The basic idea using template specializations
template<int i>
struct GetKey;
template<>
struct GetKey<0>
{
KeyClassA From(const Bar& arg) { return KeyClassA(arg.fieldA); }
};
template<>
struct GetKey<1>
{
KeyClassB From(const Bar& arg) { return KeyClassB(arg.fieldB); }
};
template<>
struct GetKey<2>
{
KeyClassC From(const Bar& arg) { return KeyClassC(arg.fieldC); }
};
template<int i, int N>
struct Iterate
{
static void Body(Array& array, const Bar& arg)
{
Data* data = array[i]->find(GetKey<i>().From(arg));
// DoSomething(data);
Iterate<i+1, N>::Body(array, arg);
}
};
template<int N>
struct Iterate<N, N>
{
static void Body(Array& array, const Bar&) {}
};
void Foo(Array& array, const Bar& arg)
{
Iterate<0, 3>::Body(array, arg);
}
Не понимаю. Что именно в вашем массиве? Почему вы решили объединить эти конкретные вещи в массив? Какую проблему вы пытаетесь решить путем «сопоставления ключей» с каждым элементом? –
@KarlKnechtel Без особой специфики, вот моя ситуация: – itchy23
@KarlKnechtel У меня есть шаблонный класс DataStructure, который выполняет функцию сравнения для вставки и удаления данных и принимает другую аналогичную функцию для поиска данных. Отправка типа копии данных для поиска, а затем использования первоначально заданной функции сравнения для поиска данных кажется пустой тратой по сравнению с предоставлением только функции для этого. В моей реализации мне требуется 4 'DataStructure>', поэтому они входят в массив, каждый из которых сортируется по полям в SimpleStruct, но не в том же. –
itchy23