История изменений
Исправление
pavlick,
(текущая версия)
:
В стандарте где-то расписан весь процесс матчинга, но то чтиво не для слабонервных.
Да, там без бутылки сложно разобраться, я сейчас попытался въехать, плюнул
Может deduction guides в данном случае могли бы помочь
Я тут позабавлялся, такое родил (я не претендую на лучшую реализацию, такое бы не заюзал, да и std::function в целом в данном случае):
#include <functional>
#include <type_traits>
#include <tuple>
using namespace std;
template<typename T>
struct fn_traits;
template<typename R, typename ...Args>
struct fn_traits<std::function<R(Args...)>>
{
static constexpr size_t args_cnt = sizeof...(Args);
typedef R result_type;
template <size_t i>
struct arg {
using type = typename std::tuple_element<i, std::tuple<Args...>>::type;
};
};
template <class T>
struct S {
template <class U>
S(U &&) {}
static void test(const std::function<void(T ii)> &task) {}
};
template <class U>
S(U &&u) -> S<typename fn_traits<decltype(std::function(u))>::template arg<0>::type>;
#define call_test(fn) S(fn).test(fn)
int main() {
call_test([](int){}); // ok
}
Не, ну зато не пишем это противное <int> ))
Исправление
pavlick,
:
В стандарте где-то расписан весь процесс матчинга, но то чтиво не для слабонервных.
Да, там без бутылки сложно разобраться, я сейчас попытался въехать, плюнул
Может deduction guides в данном случае могли бы помочь
Я тут позабавлялся, такое родил (я не претендую на лучшую реализацию, такое бы не заюзал, да и std::function в целом в данном случае):
#include <functional>
#include <type_traits>
#include <tuple>
using namespace std;
template<typename T>
struct fn_traits;
template<typename R, typename ...Args>
struct fn_traits<std::function<R(Args...)>>
{
static constexpr size_t args_cnt = sizeof...(Args);
typedef R result_type;
template <size_t i>
struct arg {
using type = typename std::tuple_element<i, std::tuple<Args...>>::type;
};
};
template <class T>
struct S {
template <class U>
S(U &&) {}
static void test(const std::function<void(T ii)> &task) {}
};
template <class U>
S(U &&u) -> S<typename fn_traits<decltype(std::function(u))>::template arg<0>::type>;
#define call_test(fn) S(fn).test(fn)
int main() {
call_test([](int){}); // ok
}
Не, ну зато не пишем это противное ))
Исходная версия
pavlick,
:
В стандарте где-то расписан весь процесс матчинга, но то чтиво не для слабонервных.
Да, там без бутылки сложно разобраться, я сейчас попытался въехать, плюнул
Может deduction guides в данном случае могли бы помочь
Я тут позабавлялся, такое родил (я не претендую на лучшую реализацию, такое бы не заюзал, да и std::function в целом в данном случае):
#include <functional>
#include <type_traits>
#include <tuple>
using namespace std;
template<typename T>
struct fn_traits;
template<typename R, typename ...Args>
struct fn_traits<std::function<R(Args...)>>
{
static constexpr size_t args_cnt = sizeof...(Args);
typedef R result_type;
template <size_t i>
struct arg {
using type = typename std::tuple_element<i, std::tuple<Args...>>::type;
};
};
template <class T>
struct S {
template <class U>
S(U &&) {}
static void test(const std::function<void(T ii)> &task) {}
};
template <class U>
S(U &&u) -> S<typename fn_traits<decltype(std::function(u))>::template arg<0>::type>;
#define call_test(fn) S(fn).test(fn)
int main() {
call_test([](int){}); // ok
}