std :: to_string – 重载函数的实例超过参数列表

counter是一个int

 void SentryManager::add(std::string name,std::shared_ptr<Sentry>){ name = name + std::to_string(counter); } 

什么是阻止这个错误的最好方法? 当我懒惰的时候,我只是把这个东西做了long longlong long ,但我相信有一个更好的解决方法。

错误信息:

 sentrymanager.cpp(8): error C2668: 'std::to_string' : ambiguous call to overloaded function 

我正在使用Visual C ++ 2010 Express。

在VC ++ 2010中,有三个重载的std::to_string需要long longunsigned long longlong double ,显然int不是这些,没有一个转换比另一个( demo )更好,所以转换不能明确地/明确地做。

就真正的C ++ 11支持而言,这是VC ++ 2010标准库实现方面的一个失败–C ++ 11标准本身实际上要求重载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); 

如果所有这些超负荷都存在,你显然不会有这个问题。 然而,VC ++ 2010不是基于实际的C ++ 11标准(在发布时还不存在),而是基于N3000 (从2009年开始 ),它不要求这些额外的重载。 因此,在这里指责VC ++ 苛刻了。

在任何情况下,只有less数几个电话,使用演员来解决自己的歧义没有什么不妥:

 void SentryManager::add(std::string& name, std::shared_ptr<Sentry>) { name += std::to_string(static_cast<long long>(counter)); } 

或者,如果代码库中std::to_string使用率std::to_string ,请编写一些包装,然后使用它们 – 这样就不需要调用网站:

 #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); } 

我不能检查是否VC ++ 2010成功或失败,以上使用SFINAE; 如果失败了,下面的使用标签调度,而不是SFINAE,应该是可编译的(如果可能不太清楚):

 #include <type_traits> #include <string> namespace detail { template<typename T> inline std::string to_string(T const val, std::false_type /*is_float*/, std::false_type /*is_unsigned*/) { return std::to_string(static_cast<long long>(val)); } template<typename T> inline std::string to_string(T const val, std::false_type /*is_float*/, std::true_type /*is_unsigned*/) { return std::to_string(static_cast<unsigned long long>(val)); } template<typename T, typename _> inline std::string to_string(T const val, std::true_type /*is_float*/, _) { return std::to_string(static_cast<long double>(val)); } } // namespace detail 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>()); } 

你已经绊倒了C ++ DR 1261 ,部分读取

代码“ int i; to_string(i); ”无法编译,因为' int '在' long long '和' long long unsigned '之间是不明确的。 期望用户将数字转换为更大的types来使用to_string似乎是不合理的。

build议的决议是增加更多的重载。 GCC已经实施了这个 我想MSVC没有。