2009-11-29 5 views
2

T x (значение) обычно является лучшим выбором, поскольку он будет непосредственно инициализировать x со значением, тогда как значение T x = может создать временную в зависимости от типа значения. В специальном случае, когда значение имеет тип T, однако, я предполагаю, что выражение T x = значение будет всегда приведет к точно одному вызову конструктора копии. Я прав?Инициализация: T x (значение) по сравнению с T x = значение, когда значение имеет тип T

Я задал этот вопрос, потому что я начинаю думать, что первый синтаксис слишком уродлив и сложнее понять, особенно когда значение является результатом вызова функции. например:

  • const std::string path(attributes.data(pathAttrib));
  • const std::string path = attributes.data(pathAttrib);
+0

Спасибо за ответы! – rpg

ответ

1

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

В этих случаях не допускается дополнительное временное ограничение.

Ни одна из форм инициализации не предотвращает возникновение оптимизаций, описанных в 12.8 [class.copy]. Хотя ненормативный пример, пример из 12.8/15 использует форму инициализации для копирования-инициализации, чтобы продемонстрировать устранение двух копий в результате функции, возвращающей локальную переменную по значению инициализатору объекта. Это означает, что если value в вашем примере является временным типа T, тогда это - и операция копирования до x - может быть устранена.

5

T x(value), как правило, лучший выбор, потому что он будет непосредственно инициализировать й со значением, в то время как T x = value может создать временные в зависимости от типа значения.

Вы почти правы, лучший выбор - самый ясный синтаксис. Вот как два отличаются:

Форма инициализации (с помощью круглых скобок или =), как правило, невелик, но имеет значение, когда объект инициализируется имеет тип класса ... [8,5/11]

struct A { 
    A(int) {} 
}; 
struct B { 
    explicit B(int) {} 
}; 

int main() { 
    { A obj (42); } // succeeds 
    { A obj = 42; } // succeeds 

    { B obj (42); } // succeeds 
    { B obj = 42; } // fails 
} 

требуется неявное преобразование, поэтому такие вещи, как vector<int> v = 3; неудачу, но выглядит неправильно так или иначе, не так ли? Возможна любая копия elided. Я не помню, чтобы найти это как узкое место во всем, что я написал, и я перестал беспокоиться об этом давно: просто используйте самый ясный синтаксис.


В частном случае, когда значение имеет тип T, хотя, я думаю, что выражение T x = value всегда приведет к точно один экземпляр вызова конструктора. Я прав?

Нет, вам не гарантируется, что копия ctor будет всегда вызываться, но она должна быть доступна. Например, в вашем конкретном случае выше, когда value является возвращаемым значением функции, стандарт явно разрешает удаление этих копий.

+2

Но нет копии и семантической разницы, если 'значение' имеет тип' T', что и спрашивает вопрос. [8.5/14] –

+0

Ничто в/14 не гарантирует, что копия отсутствует, и копия ctor отменяется или не применяется. Но да, я ответил в более общем плане, чем это требовалось. – 2009-11-29 20:09:58

+1

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

Смежные вопросы