Почему возвращаемое по значению должно быть const для не встроенных типов, а не const для встроенных типов? - PullRequest
4 голосов
/ 19 марта 2012

Решения 4 и 5 по ПОЛУЧЕНО # 6 Const-Correctness упомяните это:

Point GetPoint( const int i ) {
    return points_[i];
}

Возвращаемое значение обычно должно быть постояннымдля не встроенных типов возвращаемых данных ..


int GetNumPoints() {
    return points_.size();
}

.. , поскольку int уже является rvalue, а ввод 'const' может помешать созданию экземпляра шаблона и вводит в заблуждение, вводит в заблуждение,и, вероятно, откорма .

У меня есть следующие вопросы

  1. Какому экземпляру шаблона мы вмешиваемся здесь?!
  2. Что именно вводит в заблуждениездесь и почему?
  3. Почему это различие между не встроенными и встроенными.Я думал, что это плохая практика!

Ответы [ 2 ]

4 голосов
/ 19 марта 2012
Return-by-value should normally be const for non-builtin return types ..

Это не правильно - одна из относительно немногих ошибок в GotW. const Значения r были сомнительными в C ++ 03 и определенно очень плохими в C ++ 11.

Проблема в том, что в C ++ 03 у rvalues ​​может быть любая вызванная функция-член, даже неконстантная. Это замечательно, потому что вы можете "swaptimize" или выполнять цепочки методов и другие вещи, которые идеально подходят и имеют абсолютный смысл, но это также плохо, потому что компилятор не может поймать вас, когда вы делаете что-то глупое, например, присваивание ему или что-то в этом роде , Как правило, плохая идея ограничивать всех от хороших дел, потому что вызывающий может сделать что-то глупое. Намерение хорошее, но не правильное.

В C ++ 11 это исправлено, потому что вы можете запретить вызов функций-членов для значений rvalue, а во-вторых, потому что для правильной работы семантики перемещения значение rvalue должно быть изменяемым. Вы не можете взять ресурсы из rvalue, если оно const.

Как примечание, причина этого в том, что у примитивных типов всегда была специальная формулировка, встроенная в язык, например, присвоение rvalues ​​незаконно, поэтому не нужно было пытаться применять его самостоятельно, делая это const.

Что касается шаблонов, я на самом деле не уверен. Уже было известно, что эта практика была плохой, когда я начал писать код на C ++, поэтому мне никогда не приходилось сталкиваться с этим.

3 голосов
/ 19 марта 2012

Лично я не согласен с рекомендацией помещать const в возвращаемое значение независимо от семантики перемещения: значение уже является r-значением, и в результате нет большой опасности его случайного изменения. Это часть того, почему нужно ставить const на не встроенные типы: они могут содержать какой-то бэкдор к значению. Например, std::vector<T> имеет метод swap(), который можно использовать для «кражи» содержимого неконстантного значения:

std::vector<int> f();
std::vector<int> value;
f().swap(value);

Аналогично, у потоков есть некоторые операторы-члены, которые позволяют вам использовать их с некоторыми встроенными функциями, которые эффективно извлекают ссылку из потока, например ::

std::string word;
std::istringstream("hello, world") >> std::skipws >> word;

Без std::skipws поток является значением, которое нельзя привязать к первому аргументу std::operator>> (std::istream&, std::string&), но использование оператора-члена для манипуляторов возвращает неконстантную ссылку на поток.

const для встроенных типов на самом деле вообще не действует. В частности, при передаче результата функции в шаблон функции (в C ++ 2003) он не может различить передаваемый возврат const или не const. В результате это может выглядеть так, как будто const влияет на встроенный возврат, хотя на самом деле это не так.

Как я уже сказал, я не согласен с правилом, и в C ++ 2011 оно определенно не выполняется, потому что вы хотите, чтобы мог в любом случае отключить не встроенную систему, что было бы запрещено const возврат.

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