Могу ли я вернуть опциональную функцию constexpr?

  • Могу ли я вернуть optional из constexpr функционировать?
  • Зачем?
  • Если да, то как это работает?

Я заинтересован в обоих boost::optional а также std::optional, Они ведут себя одинаково?

10

Решение

boost::optional не может быть возвращен constexpr функция. Или, по крайней мере, документация не дает гарантии этого.

Тем не мение, std::optionalв соответствии с принятым предложением C ++ 14, Можно быть возвращенным constexpr функция. Но только если аргумент типа optional тривиально разрушаемо.

Это позволяет деструктору std::optional быть тривиальным в этих случаях. В этот момент нетрудно уничтожить объект, поэтому ничто не мешает std::optional из буквального типа.

Предложение вполне понятно по этому вопросу. Если T тривиально разрушаемо, то большинство конструкторов optional будет constexpr, а также optional<T> будет буквальным типом. И, следовательно, он может быть создан в constexpr функция.

10

Другие решения

Boost.Optional не поддерживает constexprГлавным образом потому, что он был написан до выпуска C ++ 11.

текущее предложение для std::optional поддерживает constexpr, пока тип значения T тривиально разрушаемо. Это работает потому что constexpr конструкторы разрешены для союзов (7.1.5p4); компилятор отслеживает, какой элемент объединения инициализирован, гарантируя, что неопределенное поведение доступа к значению отключенного необязательного параметра будет обнаружено во время компиляции:

struct dummy_t {};
template <class T>
union optional_storage {
static_assert( is_trivially_destructible<T>::value, "" );
dummy_t dummy_;
T       value_;
constexpr optional_storage(): dummy_{} {}  // disengaged
constexpr optional_storage(T const& v): value_{v} {}  // engaged
~optional_storage() = default;
};

Тип значения должен быть тривиально разрушаемым, потому что constexpr полезно только с литеральными типами, которые сами должны иметь тривиальный деструктор.

Например, написание:

constexpr optional_storage<int> o{};
constexpr int i = o.value_;

gcc выдает ошибку:

error: accessing ‘optional_storage<int>::value_’ member instead of initialized
‘optional_storage<int>::dummy_’ member in constant expression
6

По вопросам рекламы [email protected]