Тип суммы в вариационном шаблоне - PullRequest
0 голосов
/ 08 ноября 2019

У меня есть шаблонная функция, определенная для шаблонов с переменным числом типов:

template<typename ...A>
void foo(std::shared_future<A>... args) {
    // ...
}

template<typename ...A>
void foo(std::future<A>&... args) {
    // ...
}

Это работает для foo(a, b, c), если a, b и c - это либо все фьючерсы, либо всеобщие фьючерсы. Как я могу адаптировать этот код для работы с любым набором шаблонов обоих типов , т.е. как с общим, так и с необработанным фьючерсами в этом случае?

1 Ответ

1 голос
/ 08 ноября 2019

Сначала вы можете принять произвольные типы Futures..., а затем использовать SFINAE, чтобы ограничить их значением std::[shared_]future:

template<class>
struct is_future_or_shared_future : std::false_type {};

template<class T>
struct is_future_or_shared_future<std::future<T>> : std::true_type {};

template<class T>
struct is_future_or_shared_future<std::shared_future<T>> : std::true_type {};

template<class... Futures, typename = std::enable_if_t<
    std::conjunction_v<is_future_or_shared_future<Futures>...>>>
void foo(Futures&... args) {
    // ...
}

Если вы хотите принять оба значения lvalue и rvalue, используйте ссылки пересылки:

template<class T>
using remove_cvref_t = std::remove_cv_t<std::remove_reference_t<T>>;

template<class... Futures, typename = std::enable_if_t<         
    std::conjunction_v<is_future_or_shared_future<remove_cvref_t<Futures>>...>>>
void foo(Futures&&... args) {
    // ...
}

Для доступа к внутреннему типу вы можете использовать класс черт:

template<class>
struct inner_type;

template<class T>
struct inner_type<std::future<T>> { 
    using type = T;
};

template<class T>
struct inner_type<std::shared_future<T>> {
    using type = T;
};

и затем написать:

typename B = std::result_of_t<
    F(typename inner_type<remove_cvref_t<Futures>>::type...)>;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...