Должны ли методы возвращать const std :: string и возвращать const std :: string_view? - PullRequest
10 голосов
/ 14 июня 2019

Предположим, у нас есть простой метод получения в классе, который возвращает const ссылку на std::string член:

const std::string& getString() const noexcept { return someString; }

С появлением std::string_view в C ++ 17, язадаетесь вопросом, есть ли у этого преимущества написания этого вместо этого:

const std::string_view getString() const noexcept { return someString; }

Есть ли у одного метода преимущества / недостатки по сравнению с другим?Ясно (поправьте меня, если я ошибаюсь), оба решения определенно будут лучше, чем это:

const char* getString() const noexcept { return someString.c_str(); }

Я видел этот связанный вопрос, но я прошу кое-что немногоотличается.

1 Ответ

14 голосов
/ 14 июня 2019

Да, вы должны написать:

const std::string& getString() const noexcept { return someString; }

Вместо (примечание: не const, потому что никогда не возвращать const значений):

std::string_view getString() const noexcept { return someString; }

Причина -у вас уже есть string.Так что вам не нужно ничего доплачивать, чтобы получить string из этого.И string имеет одно заметное семантическое отличие от произвольного string_view: это с нулевым символом в конце по гарантии.Мы знаем это.Возможно, какой-то нижестоящий пользователь должен полагаться на эту информацию.Если им нужно нулевое завершение (например, им нужно перейти на какой-то C API, который требует этого), и вы даете string_view, они должны сами сделать из него string.Вы ничего не экономите, но потенциально заставляете нижестоящих пользователей выполнять больше работы.

Если бы вместо этого у вас было vector<char> ... тогда я бы предложил вернуть span<char const> или его эквивалент.Поскольку семантической разницы нет, а вы просто предоставляете представление.

Там также отдельный аргумент о том, что:

auto x = obj.getString();

должен делать.Для этого требуется либо копия string (дорогая, но безопасная), либо фактически ссылка на нее (дешевая, но потенциально висящая).Но это не совсем похоже на ссылку, это выглядит как значение.Это широкая проблема со ссылочно-семантическими типами в целом (такие вещи, как reference_wrapper, string_view, span, tuple<T&...>, optional<T&>, если таковые существуют, и т. Д.).

ДонУ меня нет ответа на этот случай, но об этом нужно знать.

...