#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).