Вы должны быть осторожны с этим. Если вы замените 'b' любым числовым символом, вы будете молча создавать неправильную строку, используя большинство методов. См .: Правила для строковых литералов C ++, экранирующий символ .
Например, я бросил этот невинно выглядящий фрагмент в середине программы
// Create '\0' followed by '0' 40 times ;)
std::string str("\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00", 80);
std::cerr << "Entering loop.\n";
for (char & c : str) {
std::cerr << c;
// 'Q' is way cooler than '\0' or '0'
c = 'Q';
}
std::cerr << "\n";
for (char & c : str) {
std::cerr << c;
}
std::cerr << "\n";
Вот что выводит эта программа для меня:
Entering loop.
Entering loop.
vector::_M_emplace_ba
QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
Это было мое первое заявление на печать дважды, несколько непечатаемых символов, за которым следовал символ новой строки, за которым следовало что-то во внутренней памяти, которое я только что переписал (а затем напечатал, показывая, что оно было перезаписано). Хуже всего то, что даже компиляция этого с подробными и подробными предупреждениями gcc не давала мне никаких признаков того, что что-то не так, и запуск программы через valgrind не жаловался на какие-либо неправильные шаблоны доступа к памяти. Другими словами, он совершенно не обнаруживается современными инструментами.
Вы можете получить ту же самую проблему с гораздо более простым std::string("0", 100);
, но приведенный выше пример немного сложнее, и, следовательно, труднее понять, в чем дело.
К счастью, C ++ 11 дает нам хорошее решение проблемы с использованием синтаксиса списка инициализаторов. Это избавляет вас от необходимости указывать количество символов (которое, как я показал выше, вы можете сделать неправильно) и избегает объединения экранированных чисел. std::string str({'a', '\0', 'b'})
безопасен для любого строкового содержимого, в отличие от версий, которые принимают массив char
и размер.