std :: to_string – 重载函数的实例超过参数列表
counter
是一个int
void SentryManager::add(std::string name,std::shared_ptr<Sentry>){ name = name + std::to_string(counter); }
什么是阻止这个错误的最好方法? 当我懒惰的时候,我只是把这个东西做了long long
的long long
,但我相信有一个更好的解决方法。
错误信息:
sentrymanager.cpp(8): error C2668: 'std::to_string' : ambiguous call to overloaded function
我正在使用Visual C ++ 2010 Express。
在VC ++ 2010中,有三个重载的std::to_string
需要long long
, unsigned long long
和long 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没有。