Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.83/30: Рейтинг темы: голосов - 30, средняя оценка - 4.83
144 / 28 / 4
Регистрация: 06.05.2019
Сообщений: 1,839
Записей в блоге: 4

Не получается разобраться с кодом инстанцирования кортежа

20.10.2020, 20:13. Показов 6970. Ответов 97
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Ниже будет написан код и я по модульно буду сам задавать вопросы, специфику то понял но много не понятно.
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#include <iostream>
 
 
template <class T, class U>
struct Typelist
{
    typedef T head; 
    typedef U Tail;
};
class NullType 
{ };
 
template < 
    typename T1 = NullType, typename T2 = NullType, typename T3 = NullType,
    typename T4 = NullType, typename T5 = NullType
>
class MakeList
{
    typedef typename MakeList< T2, T3, T4, T5 >::Result Tail;
 
public:
    typedef Typelist<T1, Tail> Result;
};
 
template <>
class MakeList<>
{
public:
    typedef NullType Result;
};
 
template <class TList> struct Length;
template <> 
struct Length< NullType >
{
    enum { value = 0 };
};
template <class T, class U>
struct Length< Typelist<T, U> >
{
    enum { value = 1 + Length<U>::value };
};
 
template <class TList, unsigned int Index> struct TypeAt;
 
template <class Head, class Tail>
struct TypeAt<Typelist<Head, Tail>, 0>
{
    typedef Head Result;
};
 
template <class Head, class Tail, unsigned int Index>
struct TypeAt<Typelist<Head, Tail>, Index>
{
    typedef typename TypeAt<Tail, Index - 1>::Result Result;
};
 
//============ Примитивная реализация Tuple с использованием списка типов ==================
 
template <typename T, unsigned int I>
class TupleElement
{
public:
    T & get() 
    {
        return m_value;
    }
private:
    T m_value;
};
 
template <typename List, unsigned int I = 0>
class TupleImpl;
    
template <typename T, typename U, unsigned int I>
class TupleImpl<Typelist<T, U>, I>
    : public TupleElement<T, I>
    , public TupleImpl<U, I + 1>
{ };
template <unsigned int I>
class TupleImpl<NullType, I>
{ };
 
template <
    typename T1 = NullType, typename T2 = NullType, typename T3 = NullType,
    typename T4 = NullType, typename T5 = NullType    
>
class Tuple : public TupleImpl<typename MakeList<T1, T2, T3, T4, T5>::Result>
{
    typedef typename MakeList<T1, T2, T3, T4, T5>::Result ElementsList;
        
public:
    template <unsigned int Index>
    typename TypeAt<ElementsList, Index>::Result & get() 
    {
        TupleElement<typename TypeAt<ElementsList, Index>::Result, Index> & el = *this;
        return el.get();
    }
    enum 
    {
        Size = Length<ElementsList>::value
    };
    
};
 
//======================== Эмуляция перебора в цикле ====================================
template <typename Tuple, unsigned int I = Tuple::Size>
struct TupleForEach_ 
{
    template <typename F>
    static void run(Tuple & tpl, F f) 
    {
        TupleForEach_<Tuple, (I - 1)>::run(tpl, f);
        f(tpl.template get<(I - 1)>());
    }
};
 
template <typename Tuple>
struct TupleForEach_<Tuple, 0> 
{
    template <typename F>
    static void run(Tuple & tpl, F f) { }
};
 
template <typename Tuple, typename F>
void TupleForEeach(Tuple & x, F f) 
{
    TupleForEach_<Tuple>::run(x, f);
}
//=======================================================================
 
struct CoutPrinter {
    template <typename T>
    void operator()(T const & v) const 
    {
        std::cout << v << ' '; 
    }
};
 
int main()
{
    Tuple<int, char, double> tpl;
    
    tpl.get<0>() = 1;
    tpl.get<1>() = 'a';
    tpl.get<2>() = 3.14;
    
    TupleForEeach(tpl, CoutPrinter());
}
Я бы хотел бы пока понять этот модуль
C++
1
2
3
4
5
6
7
class MakeList
{
    typedef typename MakeList< T2, T3, T4, T5 >::Result Tail;
 
public:
    typedef Typelist<T1, Tail> Result;
};
который идёт за 1ой структурой struct Typelist. Значит
эту строку typedef typename MakeList<T2, T3, T4, T5>::Result Tail; я понимаю так, в поле MakeList<T2, T3, T4, T5> мы находим Result и назначаем всей этой цепочке имя Tail. Возникает вопрос откуда мы взяли элемент Result, если он не возник, он описан в public: который находится ниже этой строки?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
20.10.2020, 20:13
Ответы с готовыми решениями:

Не получается разобраться с кодом .
Пишу программу текстовый редактор , программа почти готова но не хватает печати , недавно нашол пример печати ( спасибо медведю Вини-Пуху...

Не получается разобраться с кодом (структуры)
Есть выдержка из программы: struct BAZA// структура база { char name ; char fam ; char otch ; ...

Не могу разобраться разобраться с кодом меню
Добрый день. Я понимаю, что тут все, наверное, элементарно. Но я только начала изучение js и пока для меня все страшно и сложно. Проблема...

97
76 / 68 / 10
Регистрация: 11.07.2016
Сообщений: 320
22.10.2020, 01:37
Студворк — интернет-сервис помощи студентам
get<I> - это и есть обращение к элементу по индексу.
0
144 / 28 / 4
Регистрация: 06.05.2019
Сообщений: 1,839
Записей в блоге: 4
22.10.2020, 01:49  [ТС]
Цитата Сообщение от Zirak Посмотреть сообщение
get<I> - это и есть обращение к элементу по индексу.
Я понимаю но значение будет подаваться через переменную а не константу и если я правильно понял то здесь выполняется своего рода итеративность get<(I - 1)>
C++
1
2
3
4
5
6
template <typename F>
    static void run(Tuple & tpl, F f) 
    {
        TupleForEach_<Tuple, (I - 1)>::run(tpl, f);
        f(tpl.template get<(I - 1)>());
    }
и на место I будет поставлена моя переменная а цикл там уже не будет нужен, их не нужно будет перебирать а просто выстрелить туда с первого раза и попасть в нужный тип.
0
76 / 68 / 10
Регистрация: 11.07.2016
Сообщений: 320
22.10.2020, 01:51
Цитата Сообщение от Nexi99 Посмотреть сообщение
Я понимаю но значение будет подавать через переменную а не константу
Все параметры шаблонов должны быть известны во время компиляции. Передать в get что-то, что будет известно только в рантайме невозможно.
0
144 / 28 / 4
Регистрация: 06.05.2019
Сообщений: 1,839
Записей в блоге: 4
22.10.2020, 01:54  [ТС]
может это не возможно но с другой стороны список построен и он статический а вот используемый тип не статический.

Добавлено через 1 минуту
Цитата Сообщение от Zirak Посмотреть сообщение
Все параметры шаблонов должны быть известны во время компиляции. Передать в get что-то, что будет известно только в рантайме невозможно.
так вот по этому я и спрашиваю что может можно доработать эту функцию которая например будет брать индекс из глобальной переменной и попадать на нужный тип потому что доступ к номерам индексов здесь имеется я проверял.

Добавлено через 1 минуту
также имеется и доступ к количеству списка value
0
76 / 68 / 10
Регистрация: 11.07.2016
Сообщений: 320
22.10.2020, 01:59
Цитата Сообщение от Nexi99 Посмотреть сообщение
брать индекс из глобальной переменной и попадать на нужный тип
Так get и берёт индекс. Не важно откуда, главное чтобы он был известен во время компиляции. Нужность типа, правда, не гарантируется, ведь по одному индексу может располагаться только один объект.
0
144 / 28 / 4
Регистрация: 06.05.2019
Сообщений: 1,839
Записей в блоге: 4
22.10.2020, 02:03  [ТС]
Цитата Сообщение от Zirak Посмотреть сообщение
Так get и берёт индекс. Не важно откуда, главное чтобы он был известен во время компиляции.
Во время компиляции известен список индексов и он статический и меняться не будет а вот какой из них использовать то это только в момент выполнения, нельзя ли перенастроить функцию на список индексов, чтобы не идти по циклу а взять индекс из этого списка и использовать его?

Добавлено через 23 секунды
например создать константный массив.
0
76 / 68 / 10
Регистрация: 11.07.2016
Сообщений: 320
22.10.2020, 02:10
Если ты получаешь индекс в рантайме и хочешь обратиться к конкретному элементу, то, боюсь, тебе ничего не остаётся кроме как заранее написать switch-простыню со всеми case'ами под каждый индекс. Псевдокод:

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int n; // наш рантайм-индекс
tuple<...> t; // наш кортеж
 
switch(n)
{
case 0:
    t.get<0>();
    break;
case 1:
    t.get<1>();
    break;
 
//.........
case last:
    t.get<last>();
    break;
default:
    // сообщение об ошибке
}
Можно автоматизировать макросом. Но это выглядит как говно, простите за мой французский.
0
144 / 28 / 4
Регистрация: 06.05.2019
Сообщений: 1,839
Записей в блоге: 4
22.10.2020, 03:26  [ТС]
Цитата Сообщение от Zirak Посмотреть сообщение
Если ты получаешь индекс в рантайме и хочешь обратиться к конкретному элементу, то, боюсь, тебе ничего не остаётся кроме как заранее написать switch-простыню со всеми case'ами под каждый индекс. Псевдокод:
В этом случае кортёж не нужен т.к. в case {придётся писать код} , да и это равносильно проверкам if else тогда уж лучше использовать кортёж так как есть.

Добавлено через 55 секунд
того цикла что в нём предложен мне будет достаточно просто я думал избавиться от лишних итераций
0
76 / 68 / 10
Регистрация: 11.07.2016
Сообщений: 320
22.10.2020, 22:16
В общем, нашёл вот эту тему. Адаптировал для с++98.

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
template<typename Tuple, unsigned int I = Tuple::Size>
struct TupleFor__
{
    template<typename F>
    static void run(Tuple& tpl, F f, unsigned int i)
    {
        if 
            (i == I - 1) f(tpl.template get<(I - 1)>());
        else
            TupleFor__<Tuple, (I - 1)>::run(tpl, f, i);
    }
};
 
template <typename Tuple>
struct TupleFor__<Tuple, 0> 
{
    template <typename F>
    static void run(Tuple& tpl, F f, unsigned int i) { }
};
 
template <typename Tuple, typename F>
void TupleFor_(Tuple& t, F f, unsigned int i) 
{
    TupleFor__<Tuple>::run(t, f, i);
}
 
template<typename Tuple, typename F>
void TupleFor(unsigned int first, unsigned int last, Tuple t, F f)
{
    for (unsigned int i = first; i <= last; ++i)
        TupleFor_(t, f, i);
}
Тогда можно делать так:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int main()
{
    Tuple<int, char, double, unsigned int> tpl;
    
    tpl.get<0>() = -12;
    tpl.get<1>() = 'a';
    tpl.get<2>() = 3.14;
    tpl.get<3>() = 50;
    
    unsigned int a = 0;
    unsigned int b = 0;
 
    std::cin >> a;
    std::cin >> b;
    
    TupleFor(a, b, tpl, CoutPrinter());
}
https://www.onlinegdb.com/Hk7_cIkdw
0
144 / 28 / 4
Регистрация: 06.05.2019
Сообщений: 1,839
Записей в блоге: 4
22.10.2020, 22:50  [ТС]
того цикла что в нём предложен мне будет достаточно просто я думал избавиться от лишних итераций
Цитата Сообщение от Zirak Посмотреть сообщение
run(tpl, f, i)
получается что эту функцию тоже нужно править. Потому что ранее она предложена на 2 элемента а у вас 3

Добавлено через 2 минуты
а уже понятно там вы дописали. Сложно конечно

Добавлено через 9 минут
Цитата Сообщение от Zirak Посмотреть сообщение
TupleFor__<Tuple, (I - 1)>::run(tpl, f, i);
в этой строке мы совершаем рекурсию?
0
76 / 68 / 10
Регистрация: 11.07.2016
Сообщений: 320
22.10.2020, 22:52
Да.
0
144 / 28 / 4
Регистрация: 06.05.2019
Сообщений: 1,839
Записей в блоге: 4
23.10.2020, 02:14  [ТС]
Цитата Сообщение от Zirak Посмотреть сообщение
TupleFor(a, b, tpl, CoutPrinter());
Ну вот к примеру
C++
1
TupleFor(b, b, tpl, CoutPrinter());
попадаем на строгий индекс возникает вопрос почему это работает и насколько надёжно и будет ли это работать из библиотеки? Получается что ваши 3 функции ну там они тоже есть но на 2 элемента работают в момент выполнения. А создание кортежа происходит в момент компиляции и изменить его конечно не возможно да и это особо и не нужно.

Добавлено через 3 минуты
какие элементы берутся здесь
C++
1
typedef Typelist<T1, Tail> Result;
? создаётся впечатление что это работает как диапазон.

Добавлено через 10 минут
Цитата Сообщение от Zirak Посмотреть сообщение
TupleFor(a, b, tpl, CoutPrinter());
Мне кажется что при вызове цикла на каждой итерации
C++
1
2
    for (unsigned int i = first; i <= last; ++i)
        TupleFor_(t, f, i);
каждый раз строятся рекурсии
C++
1
2
3
4
        if 
            (i == I - 1) f(tpl.template get<(I - 1)>());
        else
            TupleFor__<Tuple, (I - 1)>::run(tpl, f, i);
или я не прав?

Добавлено через 43 секунды
Или рекурсия строится один раз?

Добавлено через 14 минут
как ни крути оно туда будет бежать так что тут эти проходы не выкинешь.
0
76 / 68 / 10
Регистрация: 11.07.2016
Сообщений: 320
23.10.2020, 02:49
А почему это не должно работать? Внутри этой функции простой for, с чего бы простому for (int i = a; i <= a; ++i) не работать?

Цитата Сообщение от Nexi99 Посмотреть сообщение
насколько надёжно и будет ли это работать из библиотеки?
Настолько надёжно, насколько надёжен цикл for. Из библиотеки это в смысле из заголовочного файла отдельного? Да, а с чего бы не работать?

Цитата Сообщение от Nexi99 Посмотреть сообщение
какие элементы берутся здесь
Это выше автор кода уже всё объяснил. И даже в прошлой теме, если мне память не изменяет.

Цитата Сообщение от Nexi99 Посмотреть сообщение
Или рекурсия строится один раз?
1 раз строится для каждого кортежа.

Цитата Сообщение от Nexi99 Посмотреть сообщение
как ни крути оно туда будет бежать так что тут эти проходы не выкинешь.
Не используй кортежи и будет тебе счастье.
0
144 / 28 / 4
Регистрация: 06.05.2019
Сообщений: 1,839
Записей в блоге: 4
27.11.2020, 03:40  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Шаблон, который вы видите - это рекурсивный шаблон.
А можно ли инстанцировать 1 объект(запустить рекурсию несколько раз) здесь спрашиваю Приведите пример инстанцирования 1го объекта, с вашим примером более ли менее интуитивно дошло разобрался объяснили.
0
264 / 153 / 33
Регистрация: 29.06.2019
Сообщений: 1,549
28.11.2020, 15:23
ветку не читала...
но вот ещё вариант, если надо... (линк в комментах)
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
#include <iostream>
#include <tuple> 
 
// http://www.vishalchovatiya.com/variadic-template-cpp-implementing-unsophisticated-tuple/
 
using namespace std;
 
template <typename... Args>
void print(const std::tuple<Args...> &t) {
    std::apply([](const auto &... args) {
        ((cout << args << endl), ...);
    }, t);
}
 
template <class... Ts>
struct overloaded : Ts... {
    using Ts::operator()...;
};
 
template <class... Ts>
overloaded(Ts...) -> overloaded<Ts...>;  
 
auto f = overloaded {
    [](const int &a)        { cout << "From int: " << a << endl; },
    [](const char &b)       { cout << "From char: " << b << endl; },
    [](const string &c)     { cout << "From string: " << c << endl; },
};
 
 
int main(int argc, const char *argv[])
{
    tuple<int, char, string, string>    t(1, 'A', "ABC", "done");
    std::apply([&](const auto &... e) { (f(e), ...); }, t);
    return 0;
}
0
144 / 28 / 4
Регистрация: 06.05.2019
Сообщений: 1,839
Записей в блоге: 4
29.11.2020, 19:49  [ТС]
Цитата Сообщение от JeyCi Посмотреть сообщение
но вот ещё вариант, если надо... (линк в комментах)
шаблоны с неограниченным количеством у меня не поддерживаются да и цель как бы работать на примере приведённом здесь или по ссылке кода, только мне интересно можно ли инстанцировать 1 объект, т.е. запустить рекурсию к примеру 4 раза или больше, количество рекурсий можно задать константой.
0
264 / 153 / 33
Регистрация: 29.06.2019
Сообщений: 1,549
29.11.2020, 21:51
Цитата Сообщение от Nexi99 Посмотреть сообщение
т.е. запустить рекурсию к примеру 4 раза или больше
смысл городить рекурсии? циклом for создавайте сколько надо объектов...
0
144 / 28 / 4
Регистрация: 06.05.2019
Сообщений: 1,839
Записей в блоге: 4
01.12.2020, 00:47  [ТС]
Цитата Сообщение от JeyCi Посмотреть сообщение
смысл городить рекурсии? циклом for создавайте сколько надо объектов...
проблема в том что список можно создать на этапе компиляции, а это возможно с помощью метапраграммирования, а там только рекурсии, так что для создания объекта цикл фор не всунешь, для обработки такого объекта да можно, а вот для создания нет.
1
264 / 153 / 33
Регистрация: 29.06.2019
Сообщений: 1,549
01.12.2020, 08:32
Цитата Сообщение от Nexi99 Посмотреть сообщение
проблема в том что список можно создать на этапе компиляции
это только в вашем коде?.. можно ведь расширить класс тогда - для динамического создания списка через new... и ограничитель количества элементов задать int N (тоже ведь можно динамически в run-time задавать) ... я так думала...

Добавлено через 1 час 26 минут
наверно, всё-таки вы путаете причину и следствие?.. НЕ "for loop невозможен в compile-time -- поэтому только метапрограммирование и рекурсия"... А скорее "вы создаёте шаблоном, поэтому ваш for loop не знает в compile-time на сколько кругов зацикливать" - поэтому рекурсия...
- (т.к. шаблон компилируется для всех типов в статические функции/классы)
0
144 / 28 / 4
Регистрация: 06.05.2019
Сообщений: 1,839
Записей в блоге: 4
01.12.2020, 09:30  [ТС]
Цитата Сообщение от JeyCi Посмотреть сообщение
поэтому ваш for loop не знает в compile-time на сколько кругов зацикливать
так я про это и пишу что только метапраграммирование, у меня есть одна структура, а не список разных элементов и мне нужно запустить рекурсию N-е количество раз, при этом N известно заранее. Я хочу чтобы доступ был как tpl.get<0>() = ...; и т.д., в зависимости от того сколько элементов будет создано рекурсией, как и упоминалось ранее количество таких рекурсии заранее известно, но сложность в том что инстанцируется один объект а не список, а получить нужно список.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
01.12.2020, 09:30

Отсортировать Dictionary по ключу состоящий из кортежа, и отсортировать по второму элементу кортежа
В общем, у меня есть такой код: Dictionary&lt;(int, int), int&gt; _data = new Dictionary&lt;(int, int), int&gt;(); как его отсортировать...

Разобраться с кодом
Для чего нужна вот эта часть кода? зачем нужен этот конструктор ? как он работает? // класс строки public class my_string ...

Разобраться с кодом
Эта функция заставляет работать ctrl+'русская буква' в tkinter. Не понимаю, что делает первая строчка в функции. ...

Разобраться с кодом
Ребят, помогите разобраться. У меня мозг уже потёк. Подскажите пожалуйста, где и как это исправлять. namespace System { ...

Разобраться с кодом
Помогите, пожалуйста, разобраться с кодом)) Только недавно начала изучать с++ и не могу понять что здесь делается в этой задаче ...


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Алиса нашла кучу ошибок компиляции и запуска в проекте, который без проблем компилировался и запускался)))
anaschu 30.06.2026
Я пока посмеюся, но завтра проверю. А вообще интерсно. Дал алисе файл, в котором точно нет ошибок компиляции и запуска, и попросил их найти. Нашла кучу))) Критические ошибки, мешающие компиляции и. . .
сукцессия 16. Общий обзор, в основном что бы другие ии поняли
anaschu 29.06.2026
# Передаточный документ: модель микоризной сукцессии (для нового чата) Этот документ предназначен для того, чтобы новый чат Claude мог продолжить работу без необходимости заново разбираться в. . .
сукцессия 15 неявная схема
anaschu 29.06.2026
Алиса Калибровка параметров симбиотической модели: технический обзор Содержание: Введение Постановка проблемы Технические аспекты реализации Процесс внедрения изменений
сукцессия 14. Обновленная схема модели
anaschu 28.06.2026
ГЛОБАЛЬНАЯ ОПИСАТЕЛЬНАЯ СПЕЦИФИКАЦИЯ ЭКОСИСТЕМНОЙ МОДЕЛИ «SOIL CHEMISTRY & MYCORRHIZA 2. 0» https:/ / ibb. co/ NnkGpfMd Представленная интегрированная схема описывает непрерывную нелинейную. . .
сукцессия 13. Питон модель трехзонного мицелия, пока что в основном арбускулярного
anaschu 28.06.2026
## Разработка агентной модели микоризной сукцессии: от выявления артефактов к созданию комплексной системы ### Аннотация Представлено исследование по разработке агентной модели микоризной. . .
сукцессия 12. краткий список проверок модели перед запуском.
anaschu 27.06.2026
Скрытые отказы в моделях систем динамики (SD-models) экологических систем: два случая из практики Контекст Разбирался прототип модели систем динамики (SD-модели) микоризной сукцессии: пять. . .
Сукцессия 11. Проверка орудий перед войной: разработка через тестирование
anaschu 27.06.2026
Как не дать модели соврать самой себе: проверки для симуляции микоризной сукцессии Введение Когда вы строите математическую модель живой системы — грибов, растений, почвы — главная опасность. . .
10 сукцессия. Питон код войны грибов и растений
anaschu 27.06.2026
import numpy as np class PlantAgent: def __init__(self, name, strategy, initial_biomass): self. name = name self. strategy = strategy # "greedy" (широколиственные) или. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru