Const-корректность для нетривиальных переменных - PullRequest
5 голосов
/ 12 марта 2019

(отчасти вдохновлен этим ответом хотя и не связан)

Мне всегда говорили (и говорили), что сохранение const -корректности даже для короткоживущих переменных является ценной и хорошей практикой, например:

const std::string a = "Hello world";

Вместо

std::string a = "Hello world";

Это:

  • Более ясно выражает намерение.
  • Обеспечивает, чтобы переменная была неизменной, поэтому передача ее какой-либо функции, которая может изменить ее, заставит компилятор кричать на вас.
  • Может повысить производительность благодаря оптимизации компилятора.

Хотя с тех пор, как современный C ++ ввел elision elision, в стандарте было несколько предложений, позволяющих компилятору вызывать конструктор перемещения вместо конструктора копирования:

В следующих контекстах инициализации копирования операция перемещения может использоваться вместо операции копирования:

(3,1) Если выражение в операторе return ([stmt.return]) является (возможно, заключенным в скобки) id-выражением, которое присваивает объекту имя с продолжительность автоматического хранения, заявленная в теле или Параметр-объявление-предложение самой внутренней включающей функции или лямбда-выражение или

( 3.2) если операнд throw-expression ([expr.throw]) является именем энергонезависимого автоматического объекта (кроме функции или предложения catch) параметр), область которого не выходит за пределы самого внутреннего try-block (если есть)

Означает ли это, что на самом деле может быть снижение производительности за использование const объектов с конструктором копирования / перемещения, отличным от заданного по умолчанию, вместо увеличения при столкновении с ситуациями, к которым применился бы этот вид исключения?

1 Ответ

3 голосов
/ 12 марта 2019

Означает ли это, что на самом деле может быть снижение производительности за использование const-объектов с конструктором копирования / перемещения, отличным от заданного по умолчанию

Потенциально да. При возврате локального объекта constness не позволяет использовать конструкцию перемещения, которая была бы разрешена в указанных правилах. Однако на практике может не наблюдаться ухудшение производительности, поскольку NRVO может по-прежнему исключать полное копирование / перемещение независимо от того, является ли переменная постоянной или нет.

NRVO не гарантируется и не всегда возможен - или просто не включен (отладочные сборки), поэтому может стоить использовать non-const при возврате локальных переменных по значению.

...