c++ - 检查某种类型是否是模板类 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++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>>>;
这是一个演示。