Операторы преобразования ссылочного типа: поиск неприятностей?

  1. Не нажимай бежать никогда. См. Этот ответ, чтобы узнать, почему . Как уже упоминалось выше, Ctrl-C является лучшей альтернативой. Я настоятельно рекомендую сопоставить ключ блокировки вашей заглавной буквы, чтобы сбежать.

  2. Если вы редактируете язык, совместимый с ctags, использование файла тегов, а также: ta, ctrl-] и т. Д. Является отличным способом навигации по коду, даже по нескольким файлам. Кроме того, выполнение ctrl-n и ctrl-p с использованием файла тегов - отличный способ сократить количество нажатий клавиш.

  3. Если вы редактируете строку, которая обернута, потому что она шире, чем ваш буфер, вы можете перемещаться вверх / вниз с помощью gk и gj.

  4. Постарайтесь сосредоточиться на эффективном использовании команд движения, прежде чем выучите вредные привычки. Такие вещи, как использование «dt» или «d3w» вместо нескольких нажатий на кнопку «x». По сути, всякий раз, когда вы обнаруживаете, что нажимаете одну и ту же клавишу несколько раз, возможно, есть лучший, более быстрый, более лаконичный способ выполнить то же самое.

14
задан Jon Seigel 8 April 2010 в 03:04
поделиться

3 ответа

Дело не в том, что адрес не может быть взят (компилятор всегда может приказать положить его в стек, что он и делает с помощью ref-to-const), это вопрос программистов намерение. С интерфейсом, который принимает A &, он говорит: «Я изменю то, что находится в этом параметре, чтобы вы могли читать после вызова функции». Если вы передадите ему временное значение, то то, что он "изменил", не будет существовать после функции. Это (возможно) ошибка программирования, поэтому она запрещена. Например, рассмотрим:

void plus_one(int & x) { ++x; }

int main() {
   int x = 2;
   float f = 10.0;

   plus_one(x); plus_one(f);

   cout << x << endl << f << endl;
}

Это не компилируется, но если временные файлы могут быть привязаны к ref-to-non-const, он будет компилироваться, но даст удивительные результаты. В plus_one (f) f будет неявно преобразован во временный int, plus_one примет значение temp и увеличит его, оставив базовый float f нетронутым. Когда plus_one вернулся, это не имело бы никакого эффекта. Это почти наверняка не то, что задумал программист.


Правило иногда ошибается. Типичный пример (описанный здесь ) - это попытка открыть файл, что-то распечатать и закрыть. Вы хотели бы иметь возможность:

ofstream("bar.t") << "flah";

Но вы не можете, потому что operator << принимает ссылку на неконстантный. Вы можете разбить его на две строки или вызвать метод, возвращающий ссылку на неконстантный:

ofstream("bar.t").flush() << "flah";
16
ответ дан 1 December 2019 в 12:27
поделиться

Когда вы присваиваете значение r константной ссылке, вам гарантируется, что временное не будет уничтожено, пока ссылка не будет уничтожена. Когда вы присваиваете неконстантную ссылку, такой гарантии не дается.

int main()
{
   const A& a2= A(); // this is fine, and the temporary will last until the end of the current scope.
   A& a1 = A(); // You can't do this.
}

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

4
ответ дан 1 December 2019 в 12:27
поделиться

Ошибка, с которой могут столкнуться некоторые: компилятор MSVC (компилятор Visual Studio, проверенный с Visual Studio 2008) скомпилирует этот код без проблем. Мы использовали эту парадигму в проекте для функций, которые обычно принимали один аргумент (фрагмент данных для переваривания), но иногда хотели выполнить поиск в этом фрагменте и вернуть результаты вызывающей стороне. Другой режим был включен с помощью трех аргументов: второй аргумент был информацией для поиска (ссылка по умолчанию на пустую строку), а третий аргумент был для возвращаемых данных (ссылка по умолчанию на пустой список желаемого типа).

Эта парадигма работала в Visual Studio 2005 и 2008, и нам пришлось реорганизовать ее так, чтобы список был построен и возвращен вместо того, чтобы принадлежать вызывающему абоненту и мутировать для компиляции с g ++.

Если есть способ настроить переключатели компилятора, чтобы либо запретить такое поведение в MSVC, либо разрешить его в g ++, я был бы рад узнать; вседозволенность компилятора MSVC / ограниченность компилятора g ++ усложняют перенос кода.

3
ответ дан 1 December 2019 в 12:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: