Теперь разрешено присвоить номер 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
?
Ответы
Ответ 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 испортил полный выходной поток в вашем случае.