std::to_string - more than instance of overloaded function matches the argument list(std::to_string - 多个重载函数的实例与参数列表匹配)
问题描述
counter
是一个 int
void SentryManager::add(std::string name,std::shared_ptr){name = name + std::to_string(counter);}
阻止此错误的最佳方法是什么?当我懒惰时,我只是制作了 int long long
(或其他东西),但我相信有更好的方法来解决这个问题.
错误信息:
sentrymanager.cpp(8):错误 C2668:'std::to_string':对重载函数的调用不明确
我使用的是 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);字符串 to_string(unsigned val);字符串 to_string(long val);字符串 to_string(unsigned long val);字符串 to_string(long long val);字符串 to_string(unsigned long long val);字符串 to_string(float val);字符串 to_string(double val);字符串 to_string(long double val);
如果所有这些重载都存在,你显然不会有这个问题;然而,VC++ 2010 并不是基于实际的 C++11 标准(在发布时还不存在),而是基于 N3000(来自2009),它不调用对于这些额外的重载.因此,在这里责怪 VC++ 太苛刻了...
无论如何,对于少数调用,使用强制转换自己解决歧义并没有错:
void SentryManager::add(std::string& name, std::shared_ptr) {名称 += std::to_string(static_cast(counter));}
或者,如果您的代码库中大量使用 std::to_string
,请编写一些包装器并改用它们——这样,就不需要调用站点转换:
#include #include <字符串>模板排队类型名称 std::enable_if<std::is_integral<T>::value &&std::is_signed::value, std::string>::typeto_string(T const val) {返回 std::to_string(static_cast(val));}模板排队类型名称 std::enable_if<std::is_integral<T>::value &&std::is_unsigned::value, std::string>::typeto_string(T const val) {返回 std::to_string(static_cast(val));}模板内联类型名 std::enable_if::value, std::string>::typeto_string(T const val) {返回 std::to_string(static_cast(val));}//...void SentryManager::add(std::string& name, std::shared_ptr<Sentry>) {名称 += to_string(counter);}
<小时>
以上SFINAE的使用方式无法检测VC++ 2010是成功还是失败;如果失败,以下内容——使用标签调度而不是 SFINAE——应该是可编译的(如果可能不太清楚):
#include #include <字符串>命名空间细节{模板//is_float is_unsigned内联 std::string to_string(T const val, std::false_type, std::false_type) {返回 std::to_string(static_cast(val));}模板//is_float is_unsigned内联 std::string to_string(T const val, std::false_type, std::true_type) {返回 std::to_string(static_cast(val));}模板//is_float内联 std::string to_string(T const val, std::true_type, _) {返回 std::to_string(static_cast(val));}}模板内联 std::string to_string(T const val) {return detail::to_string(val, std::is_floating_point(), std::is_unsigned());}
counter
is an int
void SentryManager::add(std::string name,std::shared_ptr<Sentry>){
name = name + std::to_string(counter);
}
What would be the best way to stop this error? When I was being lazy I just made the int long long
(or something), but I'm sure there is a better way of solving this.
Error message:
sentrymanager.cpp(8): error C2668: 'std::to_string' : ambiguous call to overloaded function
I am using Visual C++ 2010 Express.
In VC++ 2010 there are three overloads of std::to_string
that take long long
, unsigned long long
, and long double
, respectively – clearly int
is none of these, and no one conversion is better than another (demo), so the conversion cannot be done implicitly/unambiguously.
In terms of real C++11 support, this is a failing on the part of VC++ 2010's standard library implementation – the C++11 standard itself actually calls for nine overloads of 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);
Had all of these overloads been present, you obviously wouldn't have this problem; however, VC++ 2010 wasn't based on the actual C++11 standard (which did not yet exist at the time of its release), but rather on N3000 (from 2009), which does not call for these additional overloads. Consequently, it's harsh to blame VC++ too much here...
In any case, for only a handful of calls, there's nothing wrong with using a cast to resolve the ambiguity yourself:
void SentryManager::add(std::string& name, std::shared_ptr<Sentry>) {
name += std::to_string(static_cast<long long>(counter));
}
Or, if there's heavy usage of std::to_string
in your codebase, write a few wrappers and use those instead – this way, no call-site casting is needed:
#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);
}
I can't check whether VC++ 2010 succeeds or fails with the above usage of SFINAE; if it fails, the following – using tag dispatch instead of SFINAE – should be compilable (if potentially less clear):
#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>());
}
这篇关于std::to_string - 多个重载函数的实例与参数列表匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:std::to_string - 多个重载函数的实例与参数列表匹配


基础教程推荐
- 如何在 C++ 中初始化静态常量成员? 2022-01-01
- 在 C++ 中计算滚动/移动平均值 2021-01-01
- 我有静态或动态 boost 库吗? 2021-01-01
- 静态库、静态链接动态库和动态链接动态库的 .lib 文件里面是什么? 2021-01-01
- 常量变量在标题中不起作用 2021-01-01
- 这个宏可以转换成函数吗? 2022-01-01
- 如何检查GTK+3.0中的小部件类型? 2022-11-30
- 如何将 std::pair 的排序 std::list 转换为 std::map 2022-01-01
- 如何通过C程序打开命令提示符Cmd 2022-12-09
- C++结构和函数声明。为什么它不能编译? 2022-11-07