No, i pacchetti devono essere scaduti.
Ma puoi fingere. È possibile rilevare quale sia l'ultimo tipo in un pacchetto. Se è SomeSpecialType
, puoi eseguire la tua funzione. Se non è SomeSpecialType
, puoi chiamarti in modo ricorsivo con i tuoi argomenti inoltrati e fromNum(5)
aggiunto.
Se si vuole essere fantasiosi, questo controllo può essere fatto in fase di compilazione (cioè un sovraccarico diverso) utilizzando tecniche SFINAE. Ma probabilmente non ne vale la pena, considerando che il controllo di "run-time" sarà costante su un dato sovraccarico, e quindi sarà quasi certamente ottimizzato, e SFINAE non dovrebbe essere usato alla leggera.
Questo non ti dà la firma che desideri, ma ti dà il comportamento che desideri. Dovrai spiegare la firma prevista nei commenti.
Qualcosa del genere, dopo la rimozione errori di battitura e simili:
// 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))));
}
o qualcosa di molto simile.
Quindi è come una soluzione alternativa, è una firma diversa ma lo stesso comportamento ... Vedo. In realtà stavo progettando di rimuovere quel parametro in futuro, quindi forse non ne vale la pena (e la firma sarebbe confusa). Puoi mostrarmi un semplice esempio? – cfa45ca55111016ee9269f0a52e771
@ fr33domlover Ho abbozzato il disegno. Non è stato compilato, per non parlare del debug, ma i fondamenti dovrebbero essere lì. – Yakk
Grazie, proverò se non deciderò semplicemente di rimuovere il singolo parametro. Sembra complicato e la firma non viene mantenuta, quindi potrebbe non valerne la pena ... comunque grazie – cfa45ca55111016ee9269f0a52e771