Как при помощи концептов проверить возвращаемый из функции шаблонный тип? С++

Как при помощи type traits или концептов понять, что тип std::optional<int> и std::optional<double> - это инстанцирование одного и того же класса std::optional? Как написать функцию, которая бы принимала функцию, которая возвращает std::optional<T>, где T - это любой его тип? У меня загвоздка именно в том, что я не знаю как определить, что функция возвращает именно optional.


Ответы (1 шт):

Автор решения: HolyBlackCat
template <typename T> struct IsStdOptional : std::false_type {};
template <typename T> struct IsStdOptional<std::optional<T>> : std::true_type {};

Дальше как угодно. Можно в лоб:

template <typename F>
void foo(F &&func) requires IsStdOptional<decltype(std::forward<F>(func)())>::value {}

Можно так:

template <typename T>
concept StdOptional = IsStdOptional<T>::value;

template <typename F>
void foo(F &&func) requires requires{{std::forward<F>(func)()} -> StdOptional;} {}
→ Ссылка