Компилятор не разрешен , чтобы произвольно решить преобразовать имя lvalue в значение r, которое нужно перенести из. Он может только делать это там, где это позволяет C ++-стандарт. Например, в выражении return
(и только когда его return <identifier>;
).
*to_be_filled = v;
всегда будет выполнять копию. Даже если это последний оператор, который может получить доступ к v
, он всегда является копией. Компиляторы не могут изменить это.
Мое понимание заключается в том, что return v является O (1), так как NRVO (по сути) делает v в r-значение, которое затем использует std :: vector-move-constructor.
blockquote>Это не так, как это работает. NRVO полностью устранит ход / копию. Но способность
return <identifier>;
быть rvalue не является «оптимизацией». На самом деле это требование , что компиляторы рассматривают их как rvalues.У компиляторов есть выбор относительно копирования. У компиляторов нет выбора о том, что делает
return <identifier>;
. Таким образом, вышеупомянутое будет либо вообще не двигаться (если произойдет NRVO), либо будет перемещать объект.Есть ли тонкая причина, почему бы нет?
blockquote>One причина, по которой это не допускается, заключается в том, что местоположение инструкции не должно произвольно изменять то, что делает этот оператор. См.,
return <identifier>;
всегда будет перемещаться из идентификатора (если это локальная переменная). Неважно, где это находится в функции. В силу того, что мы являемся операторомreturn
, мы знаем , что если выполняетсяreturn
, после его выполнения ничего не будет.Это не относится к произвольным операторам. Поведение выражения
*to_be_filled = v;
не должно изменяться в зависимости от того, где это происходит в коде. Вы не сможете превратить переход в копию только потому, что добавили еще одну строку в функцию.Еще одна причина заключается в том, что произвольные утверждения могут быть действительно сложными очень быстро.
return <identifier>;
очень проста; он копирует / перемещает идентификатор в возвращаемое значение и возвращается.В отличие от этого, что происходит, если у вас есть ссылка на
v
, и каким-то образом используетсяto_be_filled
. Конечно, что не может произойти в вашем случае, но как насчет других, более сложных случаев? Последнее выражение может быть, по-видимому, прочитано из ссылки на перемещенный объект.Это намного сложнее сделать в случаях
return <identifier>;
.
Группа данных будет генерироваться столько раз, сколько количество записей, которые у вас есть в вашем основном наборе данных (заполненном запросом верхнего уровня).
Если вы хотите сохранить вложенные данные в подробном полоса, которая, кстати, нормальна, вы можете сделать одну из следующих вещей:
$V{REPORT_COUNT}.intValue()==1
) непосредственно в группе Detail, а не в подзаголовке. Обратите внимание, что это всего лишь уродливый взлом, который может повлиять на производительность отчета. Ваш основной запрос по-прежнему возвращает много данных, которые вы не используете, поэтому вы должны рассмотреть другие варианты. Если вы можете переместить субрепорт из диапазона Detail, поместите его в диапазон, который позволяет переполнять, например, заголовок или итоговый диапазон. Затем:
<jasperReport>
), так что все остальные разделы, кроме Detail, будут сгенерированы