Форум программистов, компьютерный форум CyberForum.ru

Шаблоны, рекурсия, определение типов std::function - C++

Восстановить пароль Регистрация
 
stima
429 / 284 / 16
Регистрация: 22.03.2011
Сообщений: 923
Завершенные тесты: 1
05.08.2014, 12:49     Шаблоны, рекурсия, определение типов std::function #1
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <tuple>
#include <vector>
#include <iostream>
#include <functional>
#include <type_traits>
 
template<typename T>
struct function_traits;
 
template<typename R, typename ...Args>
struct function_traits<std::function<R(Args...)>>
{
    static const size_t nargs = sizeof...(Args);
 
    typedef R result_type;
 
    template <size_t i>
    struct arg
    {
        typedef typename std::tuple_element<i, std::tuple<Args...>>::type type;
    };
};
 
template <typename FType, size_t i>
struct inserter
{
    typedef typename function_traits<FType>::template arg<i> arg;
    typedef typename arg::type type;
 
    static void back_insert(std::vector<std::string>& v)
    {
        v.push_back(typeid(type).name());
        inserter<FType, i - 1>::back_insert(v);
    }
};
 
template <typename FType>
struct inserter<FType, 0>
{
    typedef typename function_traits<FType>::template arg<0> arg;
    typedef typename arg::type type;
 
    static void back_insert(std::vector<std::string>& v)
    {
        v.push_back(typeid(type).name());
    }
};
 
int main()
{
    typedef std::function<int(int)> func_type;
 
    std::vector<std::string> v;
    inserter<func_type, function_traits<func_type>::nargs>::back_insert(v);
 
    return 0;
}
Как такое (или на подобии) реализовать. Заранее спасибо.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
05.08.2014, 12:49     Шаблоны, рекурсия, определение типов std::function
Посмотрите здесь:

std::list - преобразование типов в контейнере C++
Шаблоны и определение SSE типов на этапе компиляции C++
Какая реализация лучше? std::pointer_to_binary_function vs std::function C++
Шаблоны функции для типов char C++
C++ Ошибка: no matching function for call to 'Slovare<std::basic_string<char> >::show()'
C++ Std::function для хранения функции класса
C++ Callback std::function + доступ к приватным полям класса методам которые не есть их полями
C++ Std::function на шаблонную функцию

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
DrOffset
6420 / 3794 / 877
Регистрация: 30.01.2014
Сообщений: 6,584
05.08.2014, 14:52     Шаблоны, рекурсия, определение типов std::function #2
stima, тебе не нужен tuples тут. Т.к. он некорректно будет работать, если у функции нет аргументов.
Вот я примерно накидал:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <vector>
#include <iostream>
#include <functional>
#include <type_traits>
#include <iterator>
#include <algorithm>
 
template <size_t N, typename F>
struct function_arg_num;
 
template <size_t N, typename R, typename Arg, typename ...Args>
struct function_arg_num<N, R(Arg, Args...)>
{
    typedef typename function_arg_num<N - 1, R(Args...)>::type type;
};
 
template <typename R, typename Arg, typename ...Args>
struct function_arg_num<0, R(Arg, Args...)>
{
    typedef Arg type;
};
 
template <size_t N, typename R>
struct function_arg_num<N, R()>
{
    typedef void type;
};
 
template<typename T>
struct function_traits;
 
template<typename R, typename ...Args>
struct function_traits<std::function<R(Args...)>>
{
    static const size_t nargs = sizeof...(Args);
 
    typedef R result_type;
 
    template <size_t I>
    using arg = typename function_arg_num<I, R(Args...)>::type;
};
 
template <typename FType, typename FTraits = function_traits<FType>>
struct inserter
{
    template <size_t NArgs, typename Container>
    struct insert_helper
    {
        enum { Idx = NArgs - 1 };
 
        static void back_insert(Container & c)
        {
            c.push_back(typeid(typename FTraits::template arg<Idx>).name());
            insert_helper<NArgs - 1, Container>::back_insert(c);
        }
    };
    template <typename Container>
    struct insert_helper<0, Container>
    {
        static void back_insert(Container & c)
        {
        }
    };
 
    template <typename Container>
    static void back_insert(Container & c)
    {
        insert_helper<FTraits::nargs, Container>::back_insert(c);
    }
};
 
int main()
{
    typedef std::function<int(int, char)> func_type;
 
    std::vector<std::string> v;
    inserter<func_type>::back_insert(v);
 
    std::copy(v.begin(), v.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
}
DiffEreD
 Аватар для DiffEreD
1420 / 757 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
05.08.2014, 18:03     Шаблоны, рекурсия, определение типов std::function #3
Может уже не надо, но я как раз дописывал свое:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <iostream>
#include <tuple>
#include <utility>
#include <functional>
#include <vector>
 
template <size_t I = 0, typename Action, typename... Args>
typename std::enable_if<I == sizeof...(Args)>::type
for_each(std::tuple<Args...>&, Action)
{
}
 
template <size_t I = 0, typename Action, typename... Args>
typename std::enable_if<I != sizeof...(Args)>::type
for_each(std::tuple<Args...> &tuple, Action please)
{
   please(std::get<I>(tuple));
   for_each<I + 1, Action, Args...>(tuple, please);
}
 
 
template <typename R>
struct function_traits {};
 
template <typename R, typename... Args>
struct function_traits<std::function<R(Args...)> >
{
   typedef std::tuple<Args...> type;
};
 
struct inserter {
   std::vector<std::string>& v;
 
   inserter(std::vector<std::string>& v_) : v(v_) {}
 
   template <typename T>
   void operator()(const T& value)
   {
      v.push_back(typeid(value).name());
   }
};
 
 
int main()
{
   typedef function_traits<std::function<int(int, long, std::string, double)> >::type tuple_t;
   tuple_t t;
   std::vector<std::string> v;
   for_each(t, inserter(v));
 
   for (auto& s : v)
      std::cout << s << "\n";
}
Добавлено через 2 часа 28 минут
Подкину еще такое:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
#include <functional>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/for_each.hpp>
 
namespace mpl = boost::mpl;
 
template <typename R>
struct get_arguments
{};
 
template <typename R, typename... Args>
struct get_arguments<std::function<R(Args...)> >
{
   typedef typename mpl::vector<Args...>::type type;
};
 
struct printer
{
   template <typename U>
   void operator()(const U& x) const
   {
      std::cout << typeid(x).name() << '\n';
   }
};
 
int main()
{
   typedef std::function<int(int, char, double, short, size_t)> func_type;
 
   typedef get_arguments<func_type>::type args;
   mpl::for_each<args>(printer());
}
Yandex
Объявления
05.08.2014, 18:03     Шаблоны, рекурсия, определение типов std::function
Ответ Создать тему
Опции темы

Текущее время: 22:47. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru