检查某种类型是否是模板类 std::optional 的实例

kyb*_*kyb 1 c++ templates constexpr

这些是模板 constexpr bool 来检查某个类型是否实例化 std::optional

template<typename>   constexpr bool is_optional = false;
template<typename T> constexpr bool is_optional<std::optional<T>> = true;
template<typename T> constexpr bool is_optional<std::optional<T>&> = true;  // avoid this
static_assert(not is_optional<int>);
static_assert(is_optional<std::optional<int>>);
static_assert(is_optional<std::optional<int>&>);
Run Code Online (Sandbox Code Playgroud)

为了详尽无遗,我需要添加

template<typename T> constexpr bool is_optional<std::optional<T>const&> = true;  // avoid this
template<typename T> constexpr bool is_optional<std::optional<T>&&> = true;  // avoid this
template<typename T> constexpr bool is_optional<std::optional<T>const> = true;  // avoid this
Run Code Online (Sandbox Code Playgroud)

和可能的挥发物。看起来太麻烦了。

有没有办法只为真实情况声明一个变量?

cig*_*ien 6

在 c++20 中,你可以使用std::remove_cv_ref_t, 和一些间接来轻松地做到这一点:

template<typename>   constexpr bool is_optional_impl = false;
template<typename T> constexpr bool is_optional_impl<std::optional<T>> = true;

template<typename T> 
constexpr bool is_optional = is_optional_impl<std::remove_cvref_t<T>>;
Run Code Online (Sandbox Code Playgroud)

这将需要的照顾constvolatile&预选赛。

这是一个演示

在c++20之前,你必须更明确一点,像这样:

template<typename T> 
constexpr bool is_optional = 
  is_optional_impl<std::remove_cv_t<std::remove_reference_t<T>>>;
Run Code Online (Sandbox Code Playgroud)

这是一个演示