Nie, paczki muszą być ostatnie.
Ale możesz go sfałszować. Możesz wykryć, jaki jest ostatni typ w paczce. Jeśli jest to SomeSpecialType
, możesz uruchomić swój func. Jeśli nie jest to SomeSpecialType
, możesz rekurencyjnie wywoływać się z przekazanymi argumentami i dołączonymi fromNum(5)
.
Jeśli chcesz mieć ochotę, to sprawdzenie może zostać wykonane w czasie kompilacji (tj. Innego przeciążenia) przy użyciu technik SFINAE. Ale to prawdopodobnie nie jest warte kłopotów, biorąc pod uwagę, że kontrola "run-time" będzie stała na danym przeciążeniu, a zatem prawie na pewno zostanie zoptymalizowana, a SFINAE nie powinno być używane lekko.
To nie daje podpisu, który chcesz, ale daje ci to, czego chcesz. Będziesz musiał wyjaśnić zamierzony podpis w komentarzach.
Coś takiego, po usunięciu literówki i podobne:
// 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))));
}
lub coś znacznie takiego.
To jest jak obejście, to inna sygnatura, ale to samo zachowanie ... Rozumiem. Właściwie planowałem usunąć ten parametr w przyszłości, więc może nie jest to warte wysiłku (a podpis byłby mylący). Czy możesz pokazać mi prosty przykład? – cfa45ca55111016ee9269f0a52e771
@ fr33domlover Naszkicowałem projekt. Nie zostały skompilowane, nie mówiąc już debugowane, ale powinny być tam podstawy. – Yakk
Dzięki, spróbuję, jeśli nie zdecyduję się usunąć pojedynczego parametru. Wygląda na skomplikowaną, a podpis nie jest przechowywany, więc może nie być warta problemów ... w każdym razie dzięki – cfa45ca55111016ee9269f0a52e771