Si consideri il seguente codice:lista variadica vs parametro template singolo: cosa dice lo standard?
#include <iostream>
#include <type_traits>
// Variadic version
template<class... Variadic>
void f(const Variadic&... variadic)
{
std::cout<<"variadic"<<std::endl;
}
// Single version
template<class Single, class = typename std::enable_if<std::is_fundamental<Single>::value>::type>
void f(const Single& single)
{
std::cout<<"single"<<std::endl;
}
// Main
int main()
{
f(); // variadic
f(42); // single : why?
f(std::string()); // variadic
f(42, 42); // variadic
return 0;
}
Non capisco il motivo per cui la linea marcata "single" compila bene (sotto g ++ 4.6.3) e non produce un problema di risoluzione di sovraccarico. Lo standard C++ 11 dice che una funzione template con un numero fisso di parametri è preferibile rispetto a una funzione variadica che potrebbe avere la stessa firma?
Nota: il parametro 'enable_if' non ha nulla a che fare con il sovraccarico" Single "che è più specializzato, è ortogonale e serve a * rimuovere * la funzione dall'insieme di possibili sovraccarichi. –
Ma quando non si rimuove la funzione, si ottiene 'f (const int &)' che è più specializzato di 'f (const int &)'.Il fatto che il secondo parametro template sia 'enable_if' non è rilevante. ma il fatto che abbia un secondo parametro è rilevante ed è la ragione per cui viene scelto il sovraccarico. Sostituire il tipo 'enable_if' con' void' rende tale overload fattibile per 'f (std :: string())' e quindi viene anche selezionato per quella chiamata come più specializzato. –
@MatthieuM. Sono d'accordo che questo è l'intento di usare 'enable_if'. Come spiega Jonathan, un suo effetto collaterale sta rendendo il modello più specializzato per quei casi in cui non viene rimosso. –