Приоритет инициализации списка из объекта того же типа
#include <iostream>
#include <initializer_list>
using namespace std;
struct CL
{
CL(){}
CL (std::initializer_list<CL>){cout<<1;}
CL (const CL&){cout<<2;}
};
int main()
{
CL cl1;
CL cl2 {cl1}; //prints 21
}
ВотCL структура с конструктором копирования и конструктором списка инициализаторов. Я думаю, что только конструктор копирования должен быть вызван здесь, потому что в соответствии со стандартом C ++ 14, 8.5.4 / 3
Инициализация списка объекта или ссылки типа T определяется следующим образом:
- Если T является типом класса, а список инициализаторов имеет единственный элемент типа cv U, где U - это T или класс, производный от T, объект инициализируется изэтот элемент (путем инициализации копирования для инициализации копирования списка или путем прямой инициализации для инициализации прямого списка).
- Иначе, ...
Другими словами, инициализацияcl2 должен быть выполнен изcl1 элемент, но не из списка инициализаторов{} CL1, Clang и gcc оба печатают «21», только Visual Studio печатает «2», и я думаю, что это правильно.
Есть два кандидата конструкторов для принятия аргументаcl1 типа CL:
1) Конструктор сstd::initializer_list<CL>
(проходит, потому что нет такого преобразования из CL вstd::initializer_list<CL>
)
2) Скопируйте конструктор с помощью const CL & (точное совпадение только с преобразованием квалификации non-const-> const)
Кто прав? Чье поведение правильно?
Спасибо