template lookup второго порядка
От: saf_e  
Дата: 28.12.20 14:43
Оценка:
Всем привет.

не знаю как правильно это называется, но хочется чтобы в test then<int> <int> можно было не указывать:

#include <type_traits>
#include <future>

template<typename F,
                std::enable_if_t<std::is_same<typename std::result_of<F()>::type, void>::value, bool> = true>
void then(F objL_callback)
{
}

template<typename X, typename F, 
            std::enable_if_t<std::is_same<typename std::result_of<F()>::type, std::future<X>>::value, bool> = true>
void then(F objL_callback)
{
}

void test()
{
    then<int>([]
    {
        return std::future<int>();
    });

    then([]
    {
    });
}


Есть идеи?
Re: template lookup второго порядка
От: watchmaker  
Дата: 28.12.20 15:29
Оценка:
Здравствуйте, saf_e, Вы писали:

_>Есть идеи?



Проверить, что тип является специализацией (только type template parameters):
template <class T, template <class...> class Template>
struct is_specialization : std::false_type {};

template <template <class...> class Template, class... Args>
struct is_specialization<Template<Args...>, Template> : std::true_type {};


использование:
template<typename F, typename FX = typename std::result_of<F()>::type,
         std::enable_if_t<is_specialization<FX, std::future>::value, bool> = true>
void then(F objL_callback);



also: std::result_of удалили уже из языка
Re[2]: template lookup второго порядка
От: rg45 СССР  
Дата: 28.12.20 15:41
Оценка:
Здравствуйте, watchmaker, Вы писали:

W>использование:

W>
W>template<typename F, typename FX = typename std::result_of<F()>::type,
W>         std::enable_if_t<is_specialization<FX, std::future>::value, bool> = true>
W>void then(F objL_callback);
W>


Так а какова роль этого параметра по умолчанию? Без него же проще:

template<typename F,
         std::enable_if_t<is_specialization<std::result_of_t<F()>, std::future>::value, bool> = true>
void then(F objL_callback);
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[3]: template lookup второго порядка
От: watchmaker  
Дата: 28.12.20 16:38
Оценка:
Здравствуйте, rg45, Вы писали:

R>Так а какова роль этого параметра по умолчанию?


Здесь — никакого. Это артефакт редактирования.
Re[2]: template lookup второго порядка
От: saf_e  
Дата: 29.12.20 08:58
Оценка:
Здравствуйте, watchmaker, Вы писали:

W>Здравствуйте, saf_e, Вы писали:


_>>Есть идеи?



W>Проверить, что тип является специализацией (только type template parameters):

W>
W>template <class T, template <class...> class Template>
W>struct is_specialization : std::false_type {};

W>template <template <class...> class Template, class... Args>
W>struct is_specialization<Template<Args...>, Template> : std::true_type {};
W>


W>использование:

W>
W>template<typename F, typename FX = typename std::result_of<F()>::type,
W>         std::enable_if_t<is_specialization<FX, std::future>::value, bool> = true>
W>void then(F objL_callback);
W>



W>also: std::result_of удалили уже из языка


Да, про result_of в курсе, но это для С++14

Сорри, пример немного неполный, на самом деле нужно:

template<typename X, typename F, 
            std::enable_if_t<std::is_same<typename std::result_of<F()>::type, std::future<X>>::value, bool> = true>
SomeClass<X> then(F objL_callback)
{
}
Re[2]: template lookup второго порядка
От: saf_e  
Дата: 29.12.20 09:16
Оценка:
Здравствуйте, watchmaker, Вы писали:

W>Здравствуйте, saf_e, Вы писали:


_>>Есть идеи?



W>Проверить, что тип является специализацией (только type template parameters):

W>
W>template <class T, template <class...> class Template>
W>struct is_specialization : std::false_type {};

W>template <template <class...> class Template, class... Args>
W>struct is_specialization<Template<Args...>, Template> : std::true_type {};
W>


W>использование:

W>
W>template<typename F, typename FX = typename std::result_of<F()>::type,
W>         std::enable_if_t<is_specialization<FX, std::future>::value, bool> = true>
W>void then(F objL_callback);
W>



W>also: std::result_of удалили уже из языка


дубликат
Отредактировано 29.12.2020 9:17 saf_e . Предыдущая версия .
Re[3]: template lookup второго порядка
От: rg45 СССР  
Дата: 29.12.20 09:46
Оценка: 1 (1) +1
Здравствуйте, saf_e, Вы писали:

_>Сорри, пример немного неполный, на самом деле нужно:


_>
_>template<typename X, typename F, 
_>            std::enable_if_t<std::is_same<typename std::result_of<F()>::type, std::future<X>>::value, bool> = true>
_>SomeClass<X> then(F objL_callback)
_>{
_>}

_>


Тогда все еще проще. Просто "вырезаешь" и компонуешь нужный тип результата. Это тоже будет разновидностью SFINAE, только без всяких enable_if:

template <typename, template<typename> class Template>
struct arg_of_template;

template <template <typename> class Template, typename Arg>
struct arg_of_template<Template<Arg>, Template> { using type = Arg; };

template <typename T, template<typename> class Template>
using arg_of_template_t = typename arg_of_template<T, Template>::type;

template<typename F>
SomeClass<arg_of_template_t<std::result_of_t<F()>, std::future>> then(F objL_callback)
{
}


Ну либо просто обозначаешь тип возвращаемого значения как auto
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 29.12.2020 11:38 rg45 . Предыдущая версия .
Re[3]: template lookup второго порядка
От: watchmaker  
Дата: 29.12.20 09:46
Оценка: 1 (1) +1
Здравствуйте, saf_e, Вы писали:

_>Сорри, пример немного неполный, на самом деле нужно


А в чём отличие? X что-ли достать нужно? Ну так при проверке специализации он же доступен и в одну дополнительную строчку сохраняется:
template <template <class...> class Template, class... Args>
struct is_specialization<Template<Args...>, Template> : std::true_type {
    using args_type_tuple = std::tuple<Args...>;  // одна строчка
    using first_arg_type = std::tuple_element_t<0, args_type_tuple>; // ну или сразу так
};


В результате is_specialization<…>::value вернёт false/true для проверки. И во втором случае тип будет доступен через is_specialization<…>::first_arg_type — подставляй его в свой SomeClass<…>.
Re[4]: template lookup второго порядка
От: rg45 СССР  
Дата: 29.12.20 10:22
Оценка: 1 (1)
Здравствуйте, watchmaker, Вы писали:

W>А в чём отличие? X что-ли достать нужно? Ну так при проверке специализации он же доступен и в одну дополнительную строчку сохраняется:

W>
W>template <template <class...> class Template, class... Args>
W>struct is_specialization<Template<Args...>, Template> : std::true_type {
W>    using args_type_tuple = std::tuple<Args...>;  // одна строчка
W>    using first_arg_type = std::tuple_element_t<0, args_type_tuple>; // ну или сразу так
W>};
W>



Я бы и тут упростил. А попутно еще и исключил бы шаблоны с пустым списком параметров:

template <template <class...> class Template, class Arg0, class... Args>
struct is_specialization<Template<Arg0, Args...>, Template> : std::true_type {
    using first_arg_type = Arg0; // ну или сразу так
};
--
Не можешь достичь желаемого — пожелай достигнутого.
Re: template lookup второго порядка
От: saf_e  
Дата: 29.12.20 12:11
Оценка:
Всем спасибо за ответы, буду пробовать.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.