首页 > 解决方案 > 检查某种类型是否是模板类 std::optional 的实例

问题描述

这些是模板 constexpr bools,用于检查某些类型是否是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>&>);

要详尽,我需要添加

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

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

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

标签: c++templatesconstexpr

解决方案


在 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>>;

这将处理const,volatile&限定符。

这是一个演示

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

template<typename T> 
constexpr bool is_optional = 
  is_optional_impl<std::remove_cv_t<std::remove_reference_t<T>>>;

这是一个演示


推荐阅读