为什么C++允许将整数赋值给字符串?

24
今天我在程序中遇到了一个有趣的情况,我不小心将无符号整数赋值给了一个std::string。VisualStudio C++编译器没有对此发出任何警告或错误,但当我运行项目并得到我的字符串的垃圾字符时,我偶然发现了这个错误。
以下是代码大致的样子:
std::string my_string("");
unsigned int my_number = 1234;
my_string = my_number;

以下代码也能编译通过:

std::string my_string("");
unsigned int my_number = 1234;
my_string.operator=(my_number);
以下操作会产生错误:
unsigned int my_number = 1234;
std::string my_string(my_number);

发生了什么?为什么编译器会在最后一个代码块停止构建,但允许前两个代码块构建?


编译器错误是什么? 对我来说,g++ v4.4编译并正常工作。 - CsTamas
对不起,我在第二个代码块中犯了一个错误 - 它确实可以编译。最后一个失败了,因为它没有一个接受无符号整数的std :: string构造函数。 - user55417
4个回答

26
因为字符串可以从char进行赋值,而int可以隐式转换为char

为什么最后两个块没有自动转换成 int 类型?什么意思,我不能显式地调用 operator= 函数?因为以下代码可行: my_string.operator=("hello world"); - user55417
1
为什么不能显式调用operator=运算符? - CsTamas
奇怪。你的第二个例子编译无误。 - EFraim
谢谢,你可以调用operator=,至少对于类类型。 - EFraim
你说得对...第二个例子确实可以编译通过。我可能搞错了。我会进行更新的。 - user55417
显示剩余4条评论

24

std::string类定义了以下赋值运算符:

string& operator=( char ch );

这个运算符是通过将 unsigned int 隐式转换为 char 而调用的。

在第三种情况中,你使用一个显式构造函数实例化一个 std::string,但是没有可用的构造函数可以接受一个 unsigned int 或使用从 unsigned int 的隐式转换:

string();
string( const string& s );
string( size_type length, const char& ch );
string( const char* str );
string( const char* str, size_type length );
string( const string& str, size_type index, size_type length );
string( input_iterator start, input_iterator end );

3
运算符不能使用函数调用语法进行调用。C++标准中的13.5(4)说它们可以。 - Steve Jessop
运算符不能使用函数调用语法调用。那是错误的。 - sbi
1
很遗憾,因为被接受的答案一开始也犯了同样的错误,但仍然被投票赞成并得到了纠正,而这个答案在其他方面要好得多,却被投票否决了。如果它被修正了,我会投票支持它。 - Steve Jessop
显然,我的C++知识已经过时了 :) 我会修改我的答案。 - LBushkin
有没有办法在将int赋值给字符串时故意导致构建失败?例如,我希望此代码无法构建:string str; str = 0;但实际上它可以构建成功。 - Thomas Jay Rush

0

这绝对是 operator=(char ch) 的调用 - 我的调试器进入了那个函数。而且我的 MS VS 2005 编译没有出现错误。

std::string my_string("");
unsigned int my_number = 1234;
my_string = my_number;
my_string.operator=(my_number);

-1

我可以解释第一和第三种情况:

my_string = 1234;

这段代码有效是因为string覆盖了operator=(char)。实际上,你正在将一个(具有数据溢出的)字符分配到字符串中。我不知道为什么第二种情况会导致编译错误。我用GCC尝试了一下这个代码,它确实编译通过。

std::string my_string(1234);

不起作用,因为没有接受 char 或 int 参数的字符串构造函数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接