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

Почему std::string не обеспечивает преобразование в const char *?

Это скорее политический или исторический вопрос. Почему было принято решение не предоставлять преобразование const char * для std::string? Были ли опасения, что кто-то может сделать printf ( "% s", s) и верят, что он автоматически преобразуется? Есть ли открытые дискуссии по этому вопросу?

4b9b3361

Ответ 1

Автоматические броски почти всегда злые. Если был добавлен const char *, a std::string также можно было бы автоматически переключить на другие типы указателей, и это может привести к затруднению поиска ошибок. Существует метод c_str(), который возвращает const char *, чтобы вы все равно могли достичь того, что вам нужно. Кроме того, тип не логически корректен - std::string не эквивалентен const char *.

Ответ 2

Внутреннему классу string не нужно хранить строку с завершающим 0. На самом деле даже не нужно хранить их в смежной памяти, если она не захочет. Поэтому неявный листинг не имеет смысла, поскольку это может быть дорогостоящая операция.

Затем функция c_str() предоставляет вам c-строку. В зависимости от того, как библиотека хранит его внутренне, этой функции может потребоваться создать временную. Это временное действие действует только до изменения строки.

Однако, к сожалению, поскольку строка может быть указана только как c-строка внутри. Это не приведет к потере функциональности и позволит неявное преобразование.

Редактировать Стандарт в основном подразумевает, что память смежна (если доступ осуществляется через data() или оператор []), хотя он не обязательно должен быть внутренне и, конечно же, не завершен нулем. Вероятно, все реализации сохраняют и 0. Если бы это было стандартизировано, то неявное преобразование можно было бы безопасно определить.

Ответ 3

Относительно ваших предыдущих комментариев:

Если они эквивалентны, то нет никакой разницы (кроме удобства) использовать cast вместо вызова c_str()

Существует одно очень важное различие: одно неявно, а другое - явное.

С++ 0x вводит понятие операторов explicit, но до тех пор они неявные, что означает, что никогда не бывает ясно (при просмотре кода), будут ли они использоваться или нет.

Неявный бросок плохой, тем более, что они могут быть каскадированы, что приводит к крайне неясному коду.

Более того, как уже было сказано, здесь есть проблема правильности. Поскольку указатель, возвращаемый c_str, действителен только до тех пор, пока объект string не изменится, вы можете найти себя с трудными для поиска ошибок. Рассмотрим:

void function()
{
  std::map<int, char const*> map;

  map[1] = boost::lexical_cast<std::string>(47);

  std::cout << map[1] << std::endl; // CRASH here, if lucky...
}

Ответ 4

Я чувствую, что С++ - это строго типизированный язык, а неявные преобразования типов - это тип безопасности.

Он часто может укусить вас, когда преобразование происходит в том месте, где вы его не ожидаете, и может затруднить отладку вашего кода.

Неявные конструкторы могут иметь аналогичный эффект, а сам std::string имеет неявный конструктор из const char *. В этом случае это не обязательно плохо, хотя это может привести к неэффективному коду.