Подтвердить что ты не робот

Теперь разрешено присвоить номер std::string?

Рассмотрим следующий фрагмент кода:

#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 С++ 14 и GCC 4.8.4):

<no output>

Вопросы:

  • Почему фрагмент кода вообще компилируется?
  • Комментируя foo = -1, я получаю правильный stdout (1 и 2). Что компилятор, скомпилированный с foo = -1;, который приводит к сбою последующего cout?
4b9b3361

Ответ 1

foo = -1;

разрешается до std::string::operator=(char), так как -1 является int и int, теоретически может быть преобразовано в char.

Мне не понятно, что говорит стандарт, когда int не представляет допустимый char. Похоже, что в вашей реализации программа вылетает.

Обновление

Из стандарта С++ 11 (ударный удар):

3.9.1 Основные типы

1 Объекты, объявленные как символы (char), должны быть достаточно большими, чтобы хранить любой элемент базового набора символов реализаций. Если символ из этого набора хранится в символьном объекте, интегральное значение этого символа объект равен значению односимвольной литеральной формы этого символа. Определяется реализацией, может ли объект char содержать отрицательные значения.

Похоже, вам придется проконсультироваться с вашей документацией компилятора, чтобы понять, разрешает ли объект char хранить отрицательные значения, и, если да, как это относится к таким объектам.

Ответ 2

char является интегральным типом в С++. std::string определяет оператор присваивания:

std::string& operator=(char);

Так как int свободно преобразуется в char в этом контексте, диагностика не предоставляется. (Как смешно, как лучшие намерения прокладывают путь в Ад, не так ли?)

Так как (char)-1, вероятно, не является допустимым членом, если символ исполнения установлен на вашей платформе, поток входит в состояние ошибки и останется там, выводя ничего, до тех пор, пока бит ошибки не будет очищен.

EDIT это ошибка идеона. Если выходной поток содержит "незаконный" символ, весь поток не отображается, даже части, созданные и очищенные до плохого символа. Используйте другой онлайн-компилятор для проверки.

Ответ 3

Это оператор = перегрузки для строкового класса: -

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

Можете ли вы догадаться, что такое выход? Yup думаю в терминах ascii: -

1
 
A
 
2

Именно поэтому у вас нет вывода для -1.

Компилятор - MinGW - std = С++ 14 - не уверен, почему IDEONE испортил полный выходной поток в вашем случае.