Компиляторы автоматически используют семантику перемещения, когда подвижный объект используется в последний раз? - PullRequest
22 голосов
/ 22 мая 2011

В последнее время я изучал ссылки на rvalue и пришел к выводу, что весьма полезно использовать передачу по значению везде, где будет сделана полная копия объекта (полное обоснование см., Например, Как уменьшить избыточность код при добавлении перегруженных опорных операторов rvalue? и Хотите скорость? Передайте по значению! ), потому что компилятор может автоматически оптимизировать копию в таких случаях, как f(std::move(a));, где определено f как void f(A a);.

Одним отрицательным последствием передачи по значению везде является то, что весь код становится замусоренным std::move даже в таких простых случаях, как:

void Object::value(A a) 
{
    value_ = std::move(a);
}

Очевидно, если бы я написал только следующее:

void Object::value(A a) 
{
    value_ = a;
}

компилятору не должно быть сложно распознать, что a подходит к концу, даже без подсказки, и не наказывать меня дополнительной копией. Фактически, компилятор должен уметь распознавать это даже в сложных функциях.

Вопросы:

  1. Допускается ли такая оптимизация стандартом C ++ 0x?

  2. Используют ли это компиляторы? Даже в сложных случаях, т.е. функция состоит из более чем одной строки?

  3. Насколько надежна эта оптимизация, т. Е. Могу ли я ожидать, что компилятор будет использовать ее так же, как я ожидаю, что компилятор применит возвратную оптимизацию?

1 Ответ

17 голосов
/ 22 мая 2011

Разрешена ли эта оптимизация стандартом C ++ 0x?

Нет.

Используют ли ее компиляторы?Даже в сложных случаях, т. Е. Функция состоит из нескольких строк?

Нет.

Насколько надежна эта оптимизация, т. Е. Могу ли я ожидать, что компилятор ее использует?столько, сколько я ожидаю, что компилятор будет применять Оптимизацию возвращаемого значения?

Вы должны украсить A(const A&) и A(A&&) с помощью операторов печати и выполнить интересующие вас тестовые примеры.Не забудьте протестировать аргументы lvalue, если эти варианты использования являются частью вашего проекта.

Правильные ответы будут зависеть от того, насколько дорого стоят копирование и перемещение A, сколько аргументов Object::value на самом деле имеети сколько повторений кода вы готовы выдержать.

Наконец, будьте очень подозрительными любого руководства, содержащего такие слова, как "всегда" или "везде".Например, я использую goto время от времени.Но у других программистов такие слова, как «никогда», ассоциируются с goto.Но время от времени вы не можете превзойти goto как по скорости, так и по четкости.

Бывают моменты, когда вам стоит отдать предпочтение паре foo(const A&) foo(A&&) вместо foo(A).И раз ты не будешь.Ваши эксперименты с декорированными копиями и движущимися участниками помогут вам.

...