In VC++ 2010 ci sono tre sovraccarichi di std::to_string
che prendono long long
, unsigned long long
, e long double
rispettivamente - chiaramente int
è nessuna di queste, e nessuno di conversione è migliore di un altro (demo), in modo che la conversione non può essere fatto in modo implicito/senza ambiguità.
In termini di reale supporto C++ 11, questo è un difetto da parte di VC++ implementazione della libreria standard 2010 - lo standard C++ 11 si chiama in realtà per nove sovraccarichi di std::to_string
([string.conversions]/7):
string to_string(int val);
string to_string(unsigned val);
string to_string(long val);
string to_string(unsigned long val);
string to_string(long long val);
string to_string(unsigned long long val);
string to_string(float val);
string to_string(double val);
string to_string(long double val);
aveva tutti questi sovraccarichi stati presenti, ovviamente sarebbe non hanno questo problema; tuttavia, VC++ 2010 non era basato sull'effettivo standard C++ 11 (che non esisteva ancora al momento della sua versione), ma piuttosto su N3000 (da), che fa non sovraccarichi. Di conseguenza, è dura per colpa di VC++ troppo molto qui ...
In ogni caso, per solo una manciata di chiamate, non c'è niente di sbagliato con l'utilizzo di un cast per risolvere l'ambiguità da soli:
void SentryManager::add(std::string& name, std::shared_ptr<Sentry>) {
name += std::to_string(static_cast<long long>(counter));
}
oppure, se c'è un utilizzo intenso del std::to_string
nel vostro codice di base, scrivere un paio di involucri e utilizzare quelli invece - in questo modo, non è necessaria alcuna chiamata in loco casting:
#include <type_traits>
#include <string>
template<typename T>
inline
typename std::enable_if<std::is_integral<T>::value && std::is_signed<T>::value, std::string>::type
to_string(T const val) {
return std::to_string(static_cast<long long>(val));
}
template<typename T>
inline
typename std::enable_if<std::is_integral<T>::value && std::is_unsigned<T>::value, std::string>::type
to_string(T const val) {
return std::to_string(static_cast<unsigned long long>(val));
}
template<typename T>
inline typename std::enable_if<std::is_floating_point<T>::value, std::string>::type
to_string(T const val) {
return std::to_string(static_cast<long double>(val));
}
// ...
void SentryManager::add(std::string& name, std::shared_ptr<Sentry>) {
name += to_string(counter);
}
Non riesco a verificare se VC++ 2010 ha esito positivo o negativo con l'utilizzo sopra di SFINAE; se fallisce, le seguenti - utilizzando tag invio invece di SFINAE - dovrebbe essere compilabile (se potenzialmente meno chiaro):
#include <type_traits>
#include <string>
namespace detail {
template<typename T> // is_float is_unsigned
inline std::string to_string(T const val, std::false_type, std::false_type) {
return std::to_string(static_cast<long long>(val));
}
template<typename T> // is_float is_unsigned
inline std::string to_string(T const val, std::false_type, std::true_type) {
return std::to_string(static_cast<unsigned long long>(val));
}
template<typename T, typename _> // is_float
inline std::string to_string(T const val, std::true_type, _) {
return std::to_string(static_cast<long double>(val));
}
}
template<typename T>
inline std::string to_string(T const val) {
return detail::to_string(val, std::is_floating_point<T>(), std::is_unsigned<T>());
}
Potrebbe includere il messaggio di errore effettivo e quale compilatore e versione si sta utilizzando (non riproducibile con GCC 4.5). – Mat
OK - vedi modifica. – pighead10