现在允许为std :: string分配一个数字?

时间:2016-05-13 05:43:31

标签: c++ gcc

请考虑以下代码段:

#include <iostream>
int main() {
    std::string foo;
    foo = -1; // why is the compiler not complaining about this?
    std::cout << "1" << std::endl;
    std::cout << foo << std::endl;
    std::cout << "2" << std::endl;
}

实际输出(ideone.com C ++ 14模式和GCC 4.8.4):

<no output>

问题:

  1. 为什么代码片段会编译?
  2. 评论foo = -1,我得到了正确的标准输出(12)。编译器使用foo = -1;编译的导致后续cout失败的内容是什么?

3 个答案:

答案 0 :(得分:11)

foo = -1;

解析为std::string::operator=(char),因为-1intint理论上可以转换为char

int不代表有效char时,我不清楚该标准是什么。看起来在您的实现中,程序崩溃了。

<强>更新

从C ++ 11标准(强调我的):

  

3.9.1基本类型

     

1声明为字符(char)的对象应足够大,以存储实现的基本字符集的任何成员。如果此组中的字符存储在字符对象中,则为该字符的整数值   object等于该字符的单个字符文字形式的值。 实现定义char对象是否可以保存负值。

看来您必须查阅编译器的文档,以了解它是否允许char对象保留负值,如果允许,它如何处理这些对象。

答案 1 :(得分:5)

char是C ++中的整数类型。 std::string定义了赋值运算符:

std::string& operator=(char);

由于int在此上下文中自由转换为char,因此不会给出诊断。 (有意思的是,最好的意图如何铺平通往地狱的道路,不是吗?)

由于(char)-1可能不是有效成员,如果您的平台上设置了执行字符,则流进入错误状态并保持不变,不输出任何内容,直到错误位被清除。

编辑这是一个错误的错误。如果输出流包含“非法”字符,则不显示整个流,即使是在坏字符之前生成和刷新的部分。使用其他在线编译器进行检查。

答案 2 :(得分:1)

这些是字符串类的operator =重载: -

basic_string& operator=(const basic_string& str);
basic_string& operator=(basic_string&& str) noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value ||     allocator_traits<Allocator>::is_always_equal::value);
basic_string& operator=(const charT* s);
basic_string& operator=(charT c);
basic_string& operator=(initializer_list<charT>);

希望有理由为什么编译好。

现在提出你的问题,为什么没有输出。我稍微调整了一下代码: -

#include <iostream>
int main() {
    std::string foo;
    foo = -1; // why is the compiler not complaining about this?
    char ch = 65;
    std::cout << "1" << std::endl;
    std::cout << foo << std::endl;
    std::cout << ch << std::endl;
    //change ch to -1 ... ascii
    ch = -1;
    std::cout << ch << std::endl;
    std::cout << "2" << std::endl;
}

你能猜出输出是什么吗?是的,从ascii的角度来看: -

1
 
A
 
2

这正是你没有-1输出的原因。

编译器 - MinGW - std = c ++ 14 - 不确定为什么IDEONE会在你的情况下弄乱整个输出流。