我在Visual Studio 2008 / Windows SDK 7上编译以下代码时出现以下错误
const UINT a_uint;
UINT result;
throw std::runtime_error( std::string("we did ") + a_uint +
" and got " + result );
具有讽刺意味的是,我最终得到了这个结果:
error C2782: 'std::basic_string<_Elem,_Traits,_Alloc> std::operator +(
const std::basic_string<_Elem,_Traits,_Alloc> &,const _Elem
)' : template parameter '_Elem' is ambiguous
有人可以解释为什么错误信息无法解释真正的问题(没有运算符来输入字符串)?
答案 0 :(得分:6)
您可以将其减少到此
template<typename T>
void f(T, T);
int main() {
f('0', 0); // is T int or char?
}
您尝试将unsigned int添加到字符串中。这没有意义,并且std::string
类不需要采取任何预防措施来向char
添加隐式转换,因为这会隐藏这些潜在的编程错误。
尝试将unsigned int转换为std::string
为十进制/十六进制/八进制/ etc形式,然后连接(您可以使用std::ostringstream
或boost::lexical_cast
执行此操作)或修复错误在其他方面你认为合适。
答案 1 :(得分:2)
使用stringstream
(在sstream
标头中定义)撰写错误消息:
std::stringstream ss;
ss << "we did " << a_uint << " and got " << result;
throw std::runtime_error(ss.str());
答案 2 :(得分:0)
下次请发布完整错误(应该继续“[_Elem =],可能是[模糊过载列表]之一”)。
问题是您将UINT与std :: string连接起来。这不是一个有效的操作,首先必须将UINT转换为std :: string(在Google上搜索方便的函数)。编译器正在尝试尽力并尝试将一些std :: string运算符与UINT匹配。显然,它找到了一些匹配,但这些肯定不是你想要的。
答案 3 :(得分:0)
要std::string
,您只能在std::string
指定的地址和个人const char*
上添加其他char
s,ASCIIZ文字。
要连接其他类型,您可以:
使用流:
std :: ostringstream oss; oss&lt;&lt; “我们做了”&lt;&lt; a_uint&lt;&lt; “并且得到了”&lt;&lt;结果; throw std :: runtime_error(oss.str());
首先将其转换为字符串表示形式:
抛出std :: runtime_error(std :: string(“we did”)+ boost :: lexical_cast(a_uint)+ “并得到了”+ 升压:: lexical_cast的(结果));
您可能有理由怀疑为什么 C ++不会在{short,int,long,long long,float,double,unsigned short等}中为X提供operator+(std::string&, X&)
,甚至:
template <typename T>
std::string operator+(std::string& s, T& t)
{
std::ostringstream oss;
oss << t;
return s + oss.str();
}
在许多情况下,它会很方便。但是流更强大,因为你可以调整填充宽度和字符,浮点精度等。此外,char是8位整数类型,因此编译器如何知道是否附加具有该ASCII值的单个字符(例如“A”代表65),还是数字ASCII值“65”的ASCII表示? (目前它不处理任何整数,因此将其视为单个ASCII char
并不会造成混淆)。或者它应该适用于&gt; = 16位数而不是8位?这样就无法在8位整数中调整变量大小,而无需进行复杂的影响分析来查看需要重写的字符串操作。最小化依赖关系也是一种好习惯:使用字符串的一些小但可能很大百分比的翻译单元当前可能不必包括(因此花费时间解析)(因此ostream等),并且通常循环依赖性是“代码味道”并且令人沮丧的可测试性(字符串取决于ostringstream取决于字符串......)。