En VC++ 2010 hay tres sobrecargas de std::to_string
que tienen long long
, unsigned long long
, y long double
, respectivamente - con claridad int
es ninguno de estos, y nadie conversión es mejor que otro (demo), por lo que la conversión no se puede hacer de forma implícita/sin ambigüedades
En términos de apoyo real de C++ 11, se trata de un fallo por parte de VC++ implementación de la biblioteca estándar de 2010 - el estándar de C++ 11 en sí en realidad llama a nueve sobrecargas de 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);
tenía todas estas sobrecargas estado presentes, es obvio que no tendrías este problema; sin embargo, VC++ 2010 no se basó en el estándar C++ 11 real (que aún no existía en el momento de su lanzamiento), sino en N3000 (desde), que no hace no llamada para estos adicionales sobrecargas En consecuencia, es dura la culpa VC++ demasiado mucho aquí ...
En cualquier caso, sólo por un puñado de llamadas, no hay nada malo en usar un yeso para resolver la ambigüedad mismo:
void SentryManager::add(std::string& name, std::shared_ptr<Sentry>) {
name += std::to_string(static_cast<long long>(counter));
}
o bien, si hay un uso intensivo de std::to_string
en su base de código, escribir un par de envoltorios y utilizar aquellos en vez - de esta manera, no se necesita de fundición llamada in situ:
#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);
}
No puedo verificar si VC++ 2010 tiene éxito o falla con el uso anterior de SFINAE; si fracasa, el siguiente - el uso de la expedición de etiquetas en lugar de SFINAE - debe ser compilables (si es potencialmente menos clara):
#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>());
}
Podría incluir el mensaje de error real y el compilador y la versión que está utilizando (no reproducible con GCC 4.5). – Mat
Bien - ver edición. – pighead10