宏文本替換對於您的問題是無法解決的,因爲索引i
僅在運行時纔可知。在編譯甚至開始之前處理宏。
如果在編譯時不知道N
,那麼您將需要使用條件結構和可能的循環的一些組合。如果KeyClass*
ES的數量是固定的(這似乎是這種情況),你可能能夠做這樣的事情:
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);
}
我不明白。你的數組究竟是什麼?你爲什麼選擇把這些特定的東西放在一個數組中?通過「鍵匹配」每個元素的不同事物,你試圖解決什麼問題? – 2011-12-16 02:37:56
@KarlKnechtel沒有太具體,這是我的情況: – itchy23 2011-12-16 13:03:08
@KarlKnechtel我有一個模板化的`DataStructure`類,它採用比較函數來插入和刪除數據,並接受另一個類似的函數來查找數據。發送一種數據副本來查找然後使用最初給出的比較函數來查找數據似乎是一種浪費,相比之下,只是提供了一種功能來實現這一點。 在我的實現中,我需要4個`DataStructure>`,以便進入一個數組,每個數組都按`SimpleStruct`中的字段進行排序,但不是相同的。 –
itchy23
2011-12-16 13:12:22