2009-02-09 2 views
2

Это, по-видимому, очень простой вопрос - мне недавно говорили, что использование инициализации стиля C++ лучше, чем традиционное (и более общее) назначение.Оптимизация определения итератора

Так этот код:

std::SomeSTLContainer::const_iterator it = container.begin(); 
std::SomeSTLContainer::const_iterator itEnd = container.end(); 

будет «медленнее» или менее эффективен, чем:

std::SomeSTLContainer::const_iterator it (container.begin()); 
std::SomeSTLContainer::const_iterator itEnd (container.end()); 

Я понимаю причину этого - первый пример вызывает строительство по умолчанию и инициализацию затем последующее задание а не конкретную конструкцию и прямое назначение во втором примере. Однако, на современных процессорах/компиляторах, действительно ли это имеет значение?

ответ

9

Мне недавно сообщили, что использование инициализации стиля C++ лучше, чем традиционное (и более общее) назначение.

Это просто неправильно.

Я понимаю причину этого - первый пример вызывает конструкцию по умолчанию и инициализацию, а затем последующее назначение, а не конкретную конструкцию и прямое назначение во втором примере. Однако, на современных процессорах/компиляторах, действительно ли это имеет значение?

Нет, это не имеет значения. Стандарт C++ явно позволяет присваивать в этом случае опустить так, что будет создан тот же код. На практике все современных компиляторов C++ делают это.

Кроме того, Чарльз прав: это никогда не вызовет оператор присваивания, а скорее конструктор копирования. Но, как я уже сказал, даже этого не происходит.

+0

Ваш «Нет, это не относится» ко всему моему второму абзацу или просто «действительно ли это имеет значение?» вопрос? :) Если первый, можете ли вы установить меня прямо. – Konrad

+0

это относится к разнице. Подождите, я его отредактирую. –

+0

Одна из причин предпочесть вторую форму заключается в том, что, возможно, более четко сказано о том, что произойдет. Это помогает кому-то, кто читает код, понять, что будет использоваться конструктор копирования. –

3

Ваши аргументы не совсем корректны. Использование '=' в определении не вызывает конструкцию по умолчанию и назначение. В «худшем» случае он использует конструктор копирования из временного, созданного с правой стороны «=».

Если тип правой части (const/volatile в стороне) того же типа или производного типа инициализированного объекта, то две формы конструкции эквивалентны.

0

Нет, обычно. Это связано с тем, что итераторы кодируются как очень тонкие обертки, а оптимизаторы довольно агрессивны, когда дело доходит до тонких оберток. Например. обычный метод итератора - это просто операция указателя, и тело функции доступно из заголовка. Это делает его тривиально проницаемым. В этом случае копия итератора находится за кулисами, вероятно, только копия указателя, так что это имеет место.

+0

Хороший вопрос об итераторах, но не совсем применим, поскольку тот же код будет выпущен в обоих случаях даже для более тяжелых классов. –

0

Это действительно зависит от случая, и следует применять общее правило: мер.

Если существует множество экземпляров этих итераторов (возможно, во вложенных и сортированных циклах, эти более короткие конструкторы могут легко изменить ситуацию). Как бы вы ни предложили, многие компиляторы уже могут оптимизировать их самостоятельно.

Чтобы быть действительно уверены, что если ваш компилятор делает это есть только один путь: мера

0
A a = A(arg1, arg2, ...); 

Это назначение может, как указано Рудольф, заменить простой конструкцией: это строительство. И в самом деле, было бы встраивать в эквиваленте более емким

A a(arg1, arg2, ...); 

это в основном вопрос стиля, но я предпочитаю не смешивая «распайка стиле» строительство со строительством «инициализатор стиле». Таким образом, я нахожу последовательность во всем моем коде. Это сводится к: всегда используйте стиль стиля инициализации :).