C++ finale decltype nei modelli di funzione


Esempio

C ++ 11

Una delle funzioni di limitazione consiste nell'utilizzare il decltype finale per specificare il tipo restituito:

namespace details {
   using std::to_string;

   // this one is constrained on being able to call to_string(T)
   template <class T>
   auto convert_to_string(T const& val, int )
       -> decltype(to_string(val))
   {
       return to_string(val);
   }

   // this one is unconstrained, but less preferred due to the ellipsis argument
   template <class T>
   std::string convert_to_string(T const& val, ... )
   {
       std::ostringstream oss;
       oss << val;
       return oss.str();
   }
}

template <class T>
std::string convert_to_string(T const& val)
{
    return details::convert_to_string(val, 0);
}

Se chiamo convert_to_string() con un argomento con cui posso invocare to_string() , allora ho due funzioni valide per details::convert_to_string() . Il primo è preferito poiché la conversione da 0 a int è una sequenza di conversione implicita migliore rispetto alla conversione da 0 a ...

Se chiamo convert_to_string() con un argomento dal quale non posso richiamare to_string() , allora la prima istanza del modello di funzione porta a un errore di sostituzione (non c'è decltype(to_string(val)) ). Di conseguenza, quel candidato viene rimosso dal set di sovraccarico. Il secondo modello di funzione non è vincolato, quindi è selezionato e passiamo invece attraverso l' operator<<(std::ostream&, T) . Se quello non è definito, allora abbiamo un errore di compilazione difficile con uno stack di template sulla linea oss << val .