不,包必須是最後一個。
但你可以僞造它。您可以檢測包裝中的最後一種類型。如果它是SomeSpecialType
,你可以運行你的func。如果它不是SomeSpecialType
,則可以遞歸地調用你自己的轉發參數並附加fromNum(5)
。
如果您想要使用SFINAE技術,可以在編譯時(即不同的超載)完成此項檢查。但是這可能是不值得的麻煩,考慮到「運行時間」檢查將在給定的過載情況下保持不變,因此幾乎肯定會被優化,而SFINAE不應該被輕易使用。
這不會給你你想要的簽名,但它會給你你想要的行爲。您必須在評論中解釋預期的簽名。
這樣的事情,以後你刪除錯別字和其他:
// extract the last type in a pack. The last type in a pack with no elements is
// not a type:
template<typename... Ts>
struct last_type {};
template<typename T0>
struct last_type<T0> {
typedef T0 type;
};
template<typename T0, typename T1, typename... Ts>
struct last_type<T0, T1, Ts...>:last_type<T1, Ts...> {};
// using aliases, because typename spam sucks:
template<typename Ts...>
using LastType = typename last_type<Ts...>::type;
template<bool b, typename T=void>
using EnableIf = typename std::enable_if<b, T>::type;
template<typename T>
using Decay = typename std::decay<T>::type;
// the case where the last argument is SomeSpecialType:
template<
typename... Args,
typename=EnableIf<
std::is_same<
Decay<LastType<Args...>>,
SomeSpecialType
>::value
>
void func(Args&&... args) {
// code
}
// the case where there is no SomeSpecialType last:
template<
typename... Args,
typename=EnableIf<
!std::is_same<
typename std::decay<LastType<Args...>>::type,
SomeSpecialType
>::value
>
void func(Args&&... args) {
func(std::forward<Args>(args)..., std::move(static_cast<SomeSpecialType>(fromNum(5))));
}
// the 0-arg case, because both of the above require that there be an actual
// last type:
void func() {
func(std::move(static_cast<SomeSpecialType>(fromNum(5))));
}
或東西很像。
所以這就像一個解決方法,它是一個不同的簽名,但是同樣的行爲......我明白了。實際上,我打算在將來刪除這個參數,所以也許這不值得(但簽名會令人困惑)。你能告訴我一個簡單的例子嗎? – cfa45ca55111016ee9269f0a52e771 2013-02-11 02:53:57
@ fr33domlover我勾勒出了設計。尚未編譯,更不用說調試了,但基本原理應該在那裏。 – Yakk 2013-02-11 03:24:54
謝謝,我會試試看,如果我不只是決定刪除單個參數。它看起來很複雜,並且簽名沒有保存,所以它可能不值得麻煩......無論如何感謝 – cfa45ca55111016ee9269f0a52e771 2013-02-11 03:30:53