Почему std :: string не обеспечивает преобразование в const char *? - PullRequest
13 голосов
/ 04 ноября 2010

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

Ответы [ 4 ]

28 голосов
/ 04 ноября 2010

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

11 голосов
/ 04 ноября 2010

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

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

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

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

5 голосов
/ 04 ноября 2010

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

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

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

C ++ 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...
}
1 голос
/ 04 ноября 2010

Мне кажется, что C ++ является языком со строгой типизацией, и неявные преобразования типов нарушают безопасность типов.

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

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

...