Поскольку концепции C ++ 20 еще не стандартизированы, я использую static_assert
в качестве временной проверки концепции, чтобы предоставить полезные сообщения об ошибках, если требование типа не выполнено.В этом конкретном случае у меня есть функция, которая требует, чтобы тип вызывался до получения типа результата:
template <typename F, typename... Args>
void example() {
static_assert(std::is_invocable_v<F, Args...>, "Function must be callable");
using R = std::invoke_result_t<F, Args...>;
// ...
}
Кроме того, я требую, чтобы результат вызова был некоторого вида std::optional
, ноЯ не знаю, какой тип будет содержать необязательный тип, поэтому мне нужно получить этот тип из него:
using R = // ...
using T = typename R::value_type; // std::optional defines a value_type
Однако это не удастся, если тип R
не имеет value_type
,например, если это не std::optional
, как ожидалось.Я хотел бы иметь static_assert
, чтобы сначала проверить это, с другим хорошим сообщением об ошибке, если утверждение не выполнено.
Я мог бы проверить точный тип с чем-то вроде std::is_same_v
, но в этом случаеЯ не знаю точного типа.Я хочу проверить, что R
является некоторым экземпляром std::optional
, без указания , каким экземпляром он должен быть.
Один из способов сделать это с помощьючерта помощника:
template <typename T>
struct is_optional { static constexpr bool value = false; };
template <typename T>
struct is_optional<std::optional<T>> { static constexpr bool value = true; };
template <typename T>
constexpr bool is_optional_v = is_optional<T>::value;
… и тогда я могу написать:
static_assert(is_optional_v<R>, "Function's result must be an optional");
Это работает, но кажется немного неловким загрязнять мое пространство имен чертой помощника только для одного-Не проверяйте, как это.Я не ожидаю, что вам понадобится is_optional
где-либо еще, хотя я могу представить, что, возможно, в конечном итоге появятся другие одноразовые черты, такие как is_variant
или is_pair
.
Так что мне интересно: есть ли более краткий способ сделать это? Могу ли я выполнить сопоставление с образцом на экземплярах std::optional
без необходимости определения черты is_optional
и ее частичной специализации?