Можете ли вы объяснить, как контейнеры STL обрабатывают оператор присваивания с пустым списком инициализатора?
когда я сделаю что-то вроде этого:
vector<int> v;
v = { };
вызываемая функция не:
vector& operator= (initializer_list<value_type> il);
но:
vector& operator= (vector&& x);
с другой стороны, когда я сделаю нечто подобное со своим собственным классом:
struct A {
A& operator= (const A&) { return *this; }
A& operator= (A&&) { return *this; }
A& operator= (initializer_list<int>) { return *this; }
};
/* ... */
A a;
a = { };
код не компилируется на VS2013 и говорит:
error C2593: 'operator =' is ambiguous
если список не пустой, он работает нормально, он просто вызывает функцию со списком инициализаторов. проблема появляется только тогда, когда список пуст, в векторе он вызывает оператор присваивания rvalue, в моем классе выдает ошибку.
как эта ситуация обрабатывается в векторных и других контейнерах?
Это похоже на лягушатник (увидеть это в прямом эфире) и gcc (увидеть это в прямом эфире) принять эту программу и выбрать станд :: initializer_list перегрузка, которая выглядит правильно, так как это полное совпадение, это покрыто в Проект стандарта C ++ раздел раздел 13.3.3.1.5
Последовательность инициализации списка параграф 2 из примера:
void f(std::initializer_list<int>);
f( {1,2,3} ); // OK: f(initializer_list<int>) identity conversion
f( {’a’,’b’} ); // OK: f(initializer_list<int>) integral promotion
f( {1.0} ); // error: narrowing
у нас есть преобразование личности который является полное совпадение.
Для справочных перегрузок мы идем к абзацу 5 это говорит (Акцент шахты идет вперед):
В противном случае, если параметр является ссылкой, см. 13.3.3.1.4. [ Заметка: Правила в этом разделе будут применяться для инициализации основного временного для ссылки. —Конечная записка]
указывает, что временный объект создан, и мы можем применить правила к полученному временному объекту. Это будет Определяемое пользователем преобразование что хуже чем полное совпадение.
Так что это не должно быть неоднозначным.
Обновить
Похоже, есть две активные ошибки, связанные с этим:
Других решений пока нет …