boost ::variant гарантия единого хранилища

#c #boost-variant

#c #boost-вариант

Вопрос:

Моя цель — гарантировать единое хранилище для всех моих типов вариантов: согласно гарантии ‘never empty’ от Boost ::variant, нам нужно переопределить boost::has_nothrow_copy для каждого ограниченного типа. Но чуть позже в документации упоминается что-то о 'boost::blank' , и если этот тип привязан, variant установит это значение, а не попытается использовать конструкторы копирования по умолчанию.

что неясно, так это то, что добавление boost::blank в список ограниченных типов позволит избежать требования переопределения / специализации has_nothrow_copy с другими типами?

Ответ №1:

Я считаю, что это ясно. Вот соответствующий раздел из документации boost:

Соответственно, variant предназначен для включения следующих оптимизаций при выполнении следующих критериев для его ограниченных типов:

Для каждого ограниченного типа T, который не поддается копированию (как указано boost::has_nothrow_copy ), библиотека гарантирует, что variant будет использовать только одно хранилище и конструкцию на месте для T.

Если какой-либо ограниченный тип не может быть сконструирован по умолчанию (как указано boost::has_nothrow_constructor ), библиотека гарантирует, что variant будет использовать только одно хранилище и конструкцию на месте для каждого ограниченного типа в variant . Обратите внимание, однако, что в случае сбоя присваивания в левом операнде по умолчанию будет сконструирован неопределенный ограниченный тип nothrow, сконструируемый по умолчанию, чтобы сохранить гарантию never-empty .

Поскольку boost::blank по умолчанию nothrow не может быть сконструирован, применяется второе предложение. И похоже, что Boost специально выделил этот конкретный тип, который будет выбран в пользу всех остальных, так что вместо того, чтобы указывать, какой конструктивный тип по умолчанию будет создан, гарантируется, что тип будет boost::blank , если это опция.

Комментарии:

1. хм, мне пришлось прочитать это еще пару раз, прежде чем это имело смысл для моего черепа, спасибо!

2. 1 Я как раз собирался ответить на это! Вопрос был 45 минут назад! Будь ты проклят! 😉

3. Я могу подтвердить, что std::cout << boost::has_nothrow_constructor<boost::blank>::value << "n"; выводит 1 (true).