忽略缺少的完美轉發。 (假設參數在實際執行完美轉發。)獲取第n個可變參數值(不是類型)
// Base case: no args
template<typename TF> void forEach2Args(TF) { }
// Recursive case: some args
template<typename TF, typename... Ts> void forEach2Args(TF mFn, Ts... mXs)
{
mFn(getNth<0>(mXs...), getNth<1>(mXs...));
forEach2Args(mFn, getAllAfter<2>(mXs...));
}
int main()
{
int result{0};
forEach2Args([&result](auto a1, auto a2)
{
result += (a1 * a2);
}, 2, 4, 3, 6);
// roughly evaluates to:
// result += (2 * 4);
// result += (3 * 6);
}
是否有可能實現getNth
和getAllAfter
避免任何可能的運行時開銷?到目前爲止,我發現的唯一解決方案是將第一個forEach2Args
調用中的每個Ts...
放在std::tuple
的內部,然後將每個遞歸調用的非常量引用傳遞給該元組。我幾乎可以確定有不必要的移動/ ctor/dtor調用。
另一種解決方案是使用這樣的:
// Base case: no args
template<typename TF> void forEach2Args(TF) { }
// Recursive case: some args
template<typename TF, typename T1, typename T2, typename... Ts>
void forEach2Args(TF mFn, T1 mX1, T2 mX2, Ts... mXs)
{
mFn(mX1, mX2);
forEach2Args(mFn, mXs...);
}
但是這種解決方案需要,如果我想通過在3個而不是2,或任何其他數量的組參數,再次實現。我想要一些動態的地方,我可以指定通過模板參數傳遞給每個mFn
調用的參數數量。喜歡的東西:
forEachNArgs<3>([](auto a1, auto a2, auto a3){ /*...*/ }, /*...*/);
forEachNArgs<4>([](auto a1, auto a2, auto a3, auto a4){ /*...*/ }, /*...*/);
使用'的std :: tie'有不復制其參數的元組。 –
@DanielFrey:看起來'std :: tie'帶有l值引用。如果我在'mFn'調用期間傳遞給'forEach2Args'的r值引用,它會阻止正確的轉發嗎? –
@VittorioRomeo,看來正確的方法是'std :: forward_as_tuple(std :: forward(values)...)' –
chris