【问题标题】:Why does C++ allow an integer to be assigned to a string?为什么 C++ 允许将整数分配给字符串?
【发布时间】:2010-11-13 17:51:38
【问题描述】:

我今天在一个程序中遇到了一个有趣的情况,我无意中将一个无符号整数分配给了 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 可以正常编译和工作
  • 对不起,我在第二个代码块上犯了一个错误——它确实可以编译。最后一个失败,错误在于没有接受 unsigned int 的 std::string 构造函数。

标签: c++ string stl variable-assignment


【解决方案1】:

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

【讨论】:

  • 为什么 int 没有为最后 2 个块隐式转换?你是什​​么意思我不能明确地调用 operator= ?因为以下工作:my_string.operator=("hello world");
  • my_string.operator=(my_number) 不是对operator= 的显式调用吗?我在这里误会了什么?
  • "为什么 int 没有为最后 2 个块隐式转换?"因为虽然 1234 适合 16 位,并且可以有一个字符,但并非每个无符号整数都适合 16 位。一旦您指定了一个范围大于 char 的类型,您就会阻止编译器将值隐式转换为 char。
  • 为什么不能显式调用 operator= ?
  • 奇怪。你的第二个例子编译得很好。
【解决方案2】:

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

【讨论】:

  • “不能使用函数调用语法调用操作符”。 C++ 标准中的 13.5(4) 说他们可以。
  • "不能使用函数式调用语法来调用操作符"这是完全错误的。
  • 耻辱,因为接受的答案一开始犯了同样的错误,但无论如何都被投了赞成票然后更正了,而这个答案要好得多,但被否决了。如果解决了,我会投赞成票。
  • 显然,我对 C++ 的了解已经过时了 :) 我会修改我的答案。
  • 如果我将 int 分配给字符串,是否有某种方法会故意导致构建失败?例如,我希望此代码无法构建:string str; str = 0; 但它没有。
【解决方案3】:

这绝对是 operator=(char ch) 调用 - 我的调试器介入了。我的 MS VS 2005 编译后没有错误。

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

【讨论】:

    【解决方案4】:

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

    my_string = 1234;
    

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

    std::string my_string(1234);
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-26
      • 1970-01-01
      • 2023-04-02
      • 1970-01-01
      • 2013-01-25
      • 2019-02-25
      相关资源
      最近更新 更多