Некоторое время я использовал boost :: Вариант, и теперь я пытаюсь выяснить, как это работает внутри. Я написал простой тест, и я не могу понять результаты. Вот это (упрощенно)
struct my_type
{
my_type(){ cout << (size_t)this << " construction"; }
~my_type(){ cout << (size_t)this << " destruction"; }
};
int main()
{
variant<int, my_type> x;
x = my_type();
}
Выход такой программы
140736940365327 construction <-- A
140736940365236 destruction <-- ?
140736940365327 destruction <-- A
140736940365332 destruction <-- ?
Почему, черт возьми, деструктор не вызывается столько раз, сколько конструктор? Поскольку деструкторы вызываются через кучу, я знаю, что это может быть не segfault, но мне кажется, что это поведение опасно. Я что-то пропустил ? Это связано с «резервным» механизмом boost :: option?
Вы должны определить только конструктор по умолчанию, но, конечно, конструктор также может быть вызван с различными параметрами. Поскольку вы не определяете явно конструктор копирования, (конструктор, который принимает const my_type&
), компилятор неявно генерирует один для вас. Если вы добавите свой собственный конструктор копирования, вы должны увидеть, что он используется для создания двух других загадочных объектов:
struct my_type
{
my_type(){ cout << (size_t)this << " construction"; }
my_type(const my_type&){ cout << (size_t)this << " copy construction"; }
~my_type(){ cout << (size_t)this << " destruction"; }
};
Фактически, если вы используете компилятор C ++ 11, неявно сгенерированный конструктор перемещения будет отвечать за некоторые новые объекты. Если вы предоставляете конструктор копирования, как описано выше, то неявный конструктор перемещения больше не генерируется, и поэтому все они отображаются как конструкции копирования. Однако, если вы также предоставите конструктор перемещения, вы обнаружите, что он вызывается:
struct my_type
{
my_type(){ cout << (size_t)this << " construction"; }
my_type(const my_type&){ cout << (size_t)this << " copy construction"; }
my_type(my_type&&){ cout << (size_t)this << " move construction"; }
~my_type(){ cout << (size_t)this << " destruction"; }
};
Других решений пока нет …