いいえ、パックは最後にする必要があります。
しかし、あなたはそれを偽造することができます。パックの最後のタイプが何であるかを検出することができます。 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
@ fr33domlover私はデザインをスケッチしました。コンパイルされておらず、デバッグはされていませんが、基本はそこにあるはずです。 – Yakk
ただ一つのパラメータを削除するだけではない場合、私は試してみます。それは複雑に見え、署名は保持されないので、トラブルの価値がないかもしれません...とにかく感謝 – cfa45ca55111016ee9269f0a52e771