Size: a a a

2021 February 04

АК

Александр Караев... in pro.cxx
Dmitry Khominich
if constexpr работает только для шаблонных параметров функции. От шаблонных параметров класса - это будет обычный if.
нет же, почему?
источник

АК

Александр Караев... in pro.cxx
Dmitry Khominich
if constexpr работает только для шаблонных параметров функции. От шаблонных параметров класса - это будет обычный if.
у нас здесь не раст, можно использовать внешние шаблонные параметры внутри функций в constexpr контексте
источник

m

magras in pro.cxx
Dmitry Khominich
Спасибо! Да есть. Обновленный результат:


   void value() const requires std::is_same_v<T, void>  { ... }

   std::add_lvalue_reference_t<T> value() requires (!std::is_same_v<T, void>) { ... }

   std::add_lvalue_reference_t<const T> value() const requires (!std::is_same_v<T, void>) { ... }


Страшновато выглядит, но со своей задачей справляется.
Кажется для Result<void, E> все равно понадобиться специализация всего класса потому что нельзя хранить void value.
источник

АК

Александр Караев... in pro.cxx
magras
Кажется для Result<void, E> все равно понадобиться специализация всего класса потому что нельзя хранить void value.
это решается хранением [[no_unique_address]] std::conditional_t<std::is_same_v<T, void>, std::nullopt_t, T> value
источник

m

magras in pro.cxx
Александр Караев
это решается хранением [[no_unique_address]] std::conditional_t<std::is_same_v<T, void>, std::nullopt_t, T> value
Да, наверное, это решит задачу. Но мне кажется специализация выйдет более читаемой.
источник

DK

Dmitry Khominich in pro.cxx
Александр Караев
у нас здесь не раст, можно использовать внешние шаблонные параметры внутри функций в constexpr контексте
Да, можно. Но вроде все ветви if constexpr в этом случае будут инстанциированы и должны компилироваться.
источник

АК

Александр Караев... in pro.cxx
Dmitry Khominich
Да, можно. Но вроде все ветви if constexpr в этом случае будут инстанциированы и должны компилироваться.
нет, потому он и constexpr
источник

АК

Александр Караев... in pro.cxx
Dmitry Khominich
Да, можно. Но вроде все ветви if constexpr в этом случае будут инстанциированы и должны компилироваться.
источник

DK

Dmitry Khominich in pro.cxx
Понял. Я спутал с кейсом с static_assert(false), который "инстанциируется" в любой ветке constexpr:
https://godbolt.org/z/eKxYdE
источник

DK

Dmitry Khominich in pro.cxx
такой кейс не работает. Всегда срабатывает static_assert.

if constexpr (...) { ... }
else if (...) { ... }
else { static_assert(false); }
источник

АК

Александр Караев... in pro.cxx
Dmitry Khominich
такой кейс не работает. Всегда срабатывает static_assert.

if constexpr (...) { ... }
else if (...) { ... }
else { static_assert(false); }
такое решается через dependent_false, например
источник

AF

Aidar Fattakhov in pro.cxx
Dmitry Khominich
такой кейс не работает. Всегда срабатывает static_assert.

if constexpr (...) { ... }
else if (...) { ... }
else { static_assert(false); }
else if constexpr наверн еще
источник

D

Danya in pro.cxx
if constexpr (...) { ... }
else if constexpr (...) { ... }
else { static_assert(dependent_false<T>); }
источник

D

Danya in pro.cxx
template <typename T>
constexpr auto dependent_false = false;
источник

MK

Mikhail Kalugin in pro.cxx
что забавно, std::optional<void> тоже не собирается и причина похожа то что было выше.
источник

S

Stas in pro.cxx
Обсуждали же уже много раз про assert и if constexpr
источник

D

Dmitriy in pro.cxx
Mikhail Kalugin
что забавно, std::optional<void> тоже не собирается и причина похожа то что было выше.
Не думаю, ибо unique_ptr<void> собирается, а у него есть Ty& operator*()
источник

D

Dmitriy in pro.cxx
Который обычно реализуют именно с add_lvalue_reference)
источник

MK

Mikhail Kalugin in pro.cxx
Dmitriy
Не думаю, ибо unique_ptr<void> собирается, а у него есть Ty& operator*()
Ну, в VC2019, сделано иначе :)
источник

АК

Александр Караев... in pro.cxx
Dmitriy
Не думаю, ибо unique_ptr<void> собирается, а у него есть Ty& operator*()
unique_ptr хранит указатель, поэтому там нет отдельных ифов на случай void, а реализация operator* действительно требует возвращать add_lvalue_reference_t<T>
источник