#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:
- Конструктор с
std::initializer_list<CL>
(проходит, потому что такого преобразования из CL вstd::initializer_list<CL>
нет) - Конструктор копирования с const CL & (точное совпадение только с квалификационным преобразованием non-const- ›const)
Кто прав? Чье поведение правильно?
2
, как и ожидалось. - person juanchopanza   schedule 28.11.201521
, а clang 3.7 говорит2
; все версии g ++ до 5.2 говорят21
- person M.M   schedule 28.11.2015