Информация об изменениях

Сообщение std::optional ~ как value-параметр шаблона от 05.08.2023 14:25

Изменено 05.08.2023 14:47 Sm0ke

std::optional ~ как value-параметр шаблона
Есть стандартный optional, который constexpr
Попробуем взять его подставить как value param шаблона

#include <optional>
#include <cstddef>

template <std::optional<std::size_t> Size>
struct omg {};


Ошибка компиляции!

msvc ~
error C2993: 'std::optional<unsigned __int64>': is not a valid type for non-type template parameter 'Size'
message : '_Optional_construct_base<unsigned __int64>' is not a public base class

gcc ~
error: 'std::optional<long unsigned int>' is not a valid type for a template non-type parameter because it is not structural
/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/optional:705:11: note: base class 'std::_Optional_base<long unsigned int, true, true>' is not public

Я попробовал накидать минимальный велосипедный optional с constexpr
И подставить его как параметр шаблона...
Получилось!

https://godbolt.org/z/sboqbPcTW

Но есть как минимум два нюанса:
1. Этот optional Пока только для скалярного типа T (Думаю, что для остальных типов доделать специализацию является возможным)
2. Все свойства public:

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

Как сделать, чтобы было красиво? Неужели придётся смириться со вторым?
std::optional ~ как value-параметр шаблона
Есть стандартный optional, который constexpr
Попробуем взять его подставить как value param шаблона

#include <optional>
#include <cstddef>

template <std::optional<std::size_t> Size>
struct omg {};


Ошибка компиляции!

msvc ~
error C2993: 'std::optional<unsigned __int64>': is not a valid type for non-type template parameter 'Size'
message : '_Optional_construct_base<unsigned __int64>' is not a public base class

gcc ~
error: 'std::optional<long unsigned int>' is not a valid type for a template non-type parameter because it is not structural
/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/optional:705:11: note: base class 'std::_Optional_base<long unsigned int, true, true>' is not public


---

Я попробовал накидать минимальный велосипедный optional с constexpr
И подставить его как параметр шаблона...
Получилось!

https://godbolt.org/z/sboqbPcTW

Но есть как минимум два нюанса:
1. Этот optional Пока только для скалярного типа T (Думаю, что для остальных типов доделать специализацию является возможным)
2. Все свойства public:

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

Как сделать, чтобы было красиво? Неужели придётся смириться со вторым?