LINUX.ORG.RU

История изменений

Исправление 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
}