Kvark161's blog

By Kvark161, 9 years ago, In Russian

lunawyll наткнулась на прикольное поведение c++11. Попробуйте угадать, что будет выведено, если использовать c++11?

#include <set>
#include <iostream>

using namespace std;

struct S {
    int a;
    int b;
    
    S(int a = 0, int b = 0): a(a), b(b) {};

    friend bool operator < (const S& first, const S& second) {
        return first.a < second.a;
    }
};

int main() {
    set<S> s;
    s.insert({2, 1});
    cout << s.size();
}

Неожиданный результат, но в сет будет добавлено 2 элемента (a=2, b=0) и (a=1, b=0).

Почему это так? Дело в том, что в c++11 был добавлен еще один метод void insert (initializer_list<value_type> il);. Получается, что {2, 1} преобразуется в initializer_list<S> с двумя элементами (a=2, b=0) и (a=1, b=0) с помощью неявного преобразования int в S, используя конструктор, который мы описали.

GNU g++ 4.9.2 (не c++11): в сете будет один элемент (a=2, b=1).

MS VC++ 2010: ошибка компиляции.

Всем добра! :)

P.S. Каким-то образом я умудрился удалить пост, написал его заного...

UPD: О том, как я удалил пост. В английской версии сайта при редактировании поста есть кнопочка "discard" — это разве не переводится как "отмена"? Оказалось — "удалить".

  • Vote: I like it
  • +65
  • Vote: I do not like it