Ответ 1
Во втором случае вы фактически инициализируетесь только с помощью B()
; с помощью оператора запятой, A()
был построен и выброшен первым.
C {(A(), B())};
//|^^^^^^^^^^|
// \--------> (A(), B())
// ^^^ ^^^
// | |
// / \
// evaluated, THEN evaluated,
// discarded used
С другой стороны, в первом случае вы инициализируете C
из обоих временных страниц через список инициализаторов, чьи элементы также должны оцениваться слева направо, так как это происходит, но ваш компилятор не работает в этой связи:
[C++11: 8.5.4/4]:
В списке инициализаций списка с привязкой-инициализацией предложения инициализатора, включая любой результат, полученный в результате расширений пакета (14.5.3), оцениваются в порядок, в котором они появляются.. Таким образом, каждое вычисление значения и побочный эффект, связанные с данным предложением инициализатора, секвенируются перед каждым вычислением значения и побочным эффектом, связанным с любым предложением инициализатора, которое следует за ним в разделенном запятой список списка инициализаторов. [Примечание. Это упорядочение оценки выполняется независимо от семантики инициализации; например, он применяется, когда элементы списка инициализатора интерпретируются как аргументы вызова конструктора, хотя обычно нет ограничений последовательности для аргументов вызова. -end note]
Я могу воспроизвести проблему с GCC 4.8 * но Clang 3.5 ведет себя правильно & dagger;. Ошибка обсуждалась в списке std-обсуждений до & ddagger; но я еще не нашел идентификатор GCC Bugzilla еще & sect;.
C {A(), B()};
// ^^^ ^^^
// | \
// eval- THEN
// uated evaluated
// \ /
// \ /
// both used
*http://coliru.stacked-crooked.com/a/1f18e0d1f8973f3c
& dagger;http://coliru.stacked-crooked.com/a/5a6e7506e9be97c3
& ddagger;https://groups.google.com/a/isocpp.org/forum/#!topic/std-discussion/TQUnBFkUBDg
& sect;# 51253 могут быть связаны.