Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 20.10.2020, 22:30   #1
Loksiin12
Форумчанин
 
Регистрация: 04.10.2020
Сообщений: 136
По умолчанию Не получается разобраться с кодом инстанцирования кортежа

Ниже будет написан код и я по модульно буду сам задавать вопросы, специфику то понял но много не понятно.
Код:
#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());
}
Я бы хотел бы пока понять этот модуль
Код:
class MakeList
{
    typedef typename MakeList< T2, T3, T4, T5 >::Result Tail;
 
public:
    typedef Typelist<T1, Tail> Result;
};
какой здесь рассматривается Result в строке
Код:
typedef typename MakeList< T2, T3, T4, T5 >::Result Tail;
?
Loksiin12 вне форума Ответить с цитированием
Старый 21.10.2020, 14:09   #2
petya11
Пользователь
 
Регистрация: 27.09.2019
Сообщений: 68
По умолчанию

Так а в чем проблема? вы не понимаете как работает typedef, typename, оператор РОВ ::, какие значения и как передаются\возвращаются из классов? Тогда откройте туториалы, книги, видео и изучите все по отдельности. Или вам нужен наставник который это объяснит?

П.С. в вопросе нет смысловой нагрузки - это как спросить что такое int. Это легко гуглится, а за репетиторство обычно платят.
petya11 вне форума Ответить с цитированием
Старый 21.10.2020, 23:18   #3
Loksiin12
Форумчанин
 
Регистрация: 04.10.2020
Сообщений: 136
По умолчанию

Цитата:
Сообщение от petya11 Посмотреть сообщение
Так а в чем проблема? вы не понимаете как работает typedef, typename, оператор РОВ ::, какие значения и как передаются\возвращаются из классов? Тогда откройте туториалы, книги, видео и изучите все по отдельности. Или вам нужен наставник который это объяснит?

П.С. в вопросе нет смысловой нагрузки - это как спросить что такое int. Это легко гуглится, а за репетиторство обычно платят.
Ну напишите какие значения откуда и куда возвращается, что-то мне подсказывает что вы тоже не знаете.
Loksiin12 вне форума Ответить с цитированием
Старый 22.10.2020, 01:59   #4
Loksiin12
Форумчанин
 
Регистрация: 04.10.2020
Сообщений: 136
По умолчанию

Код:
template <typename F>
    static void run(Tuple & tpl, F f) 
    {
        TupleForEach_<Tuple, (I - 1)>::run(tpl, f);
        f(tpl.template get<(I - 1)>());
    }
Можно ли доработать эту функцию чтобы можно было обращаться к элементу кортежа по индексу, индекс будет передаваться в переменную а переменная будет использована здесь get<(значение переменной)>()?
Loksiin12 вне форума Ответить с цитированием
Старый 22.10.2020, 07:08   #5
Алексей1153
фрилансер
Форумчанин
 
Регистрация: 11.10.2019
Сообщений: 947
По умолчанию

Loksiin12, начни с простого, ты сразу за сложное хватанулся. Шаблоны - это метапрограммирование, то есть, это не реальный исполняющийся код, а описание-чертежи того, как сделать код, который только после этого сможет быть скомпилирован

параметры шаблона - не переменные, а типы и константы. Всё должно быть известно на этапе компилирования.
Поэтому нет смысла задавать вопрос
Цитата:
Сообщение от Loksiin12 Посмотреть сообщение
обращаться к элементу кортежа по индексу, индекс будет передаваться в переменную а переменная будет использована здесь

Разберись, например, что происходит тут.Расскажи, что понял

Код:
template<typename T>
class MyClass
{
     T arr[10];
};

int main()
{
    MyClass<int> a1;
    MyClass<double> a2;
}
Алексей1153 вне форума Ответить с цитированием
Старый 22.10.2020, 21:46   #6
Loksiin12
Форумчанин
 
Регистрация: 04.10.2020
Сообщений: 136
По умолчанию

Цитата:
Сообщение от Алексей1153 Посмотреть сообщение
Разберись, например, что происходит тут.Расскажи, что понял
Так я и начинал с простого и пришёл к этому дню. Пример приведённый вами выше очень просто в сети таких полно а вот например вот это

Код:
TupleForEach_<Tuple, (I - 1)>::run(tpl, f);
        f(tpl.template get<(I - 1)>());
в жизни подобного не видел.
Да я понял что они сильно ограничены (вчера объяснили), слишком узкая специализация, если бы то что я спросил выше было бы возможно так я бы вознёсся до небес лишние проверки можно было бы выкинуть.
Loksiin12 вне форума Ответить с цитированием
Старый 22.10.2020, 21:48   #7
Loksiin12
Форумчанин
 
Регистрация: 04.10.2020
Сообщений: 136
По умолчанию

Взять к примеру этот код
Код:
class MakeList
{
    typedef typename MakeList< T2, T3, T4, T5 >::Result Tail;
 
public:
    typedef Typelist<T1, Tail> Result;
};
Мне объяснили что Result в строке
Код:
typedef typename MakeList< T2, T3, T4, T5 >::Result Tail;
сразу же возникает и используется хотя я думал что он берётся из нижней части класса.
Loksiin12 вне форума Ответить с цитированием
Старый 23.10.2020, 07:52   #8
Алексей1153
фрилансер
Форумчанин
 
Регистрация: 11.10.2019
Сообщений: 947
По умолчанию

Цитата:
Сообщение от Loksiin12 Посмотреть сообщение
Пример приведённый вами выше очень просто
ну так расскажи подробно, что там делается. И покажи, как это бы выглядело без шаблонов
Алексей1153 вне форума Ответить с цитированием
Старый 23.10.2020, 07:53   #9
Алексей1153
фрилансер
Форумчанин
 
Регистрация: 11.10.2019
Сообщений: 947
По умолчанию

Цитата:
Сообщение от Loksiin12 Посмотреть сообщение
он берётся из нижней части класса.
у класса нет "нижней" или "верхней" части.
Алексей1153 вне форума Ответить с цитированием
Старый 23.10.2020, 22:35   #10
Loksiin12
Форумчанин
 
Регистрация: 04.10.2020
Сообщений: 136
По умолчанию

Цитата:
Сообщение от Алексей1153 Посмотреть сообщение
у класса нет "нижней" или "верхней" части.
Я не знаю что происходит здесь
Код:
typedef typename MakeList< T2, T3, T4, T5 >::Result Tail;
, если я правильно понял инструкции то мы пытаемся найти объект Result с помощью оператора области видимости :: в диапазоне MakeList< T2, T3, T4, T5 >. Мне объяснили что T1 идёт в текущую инстанцию. Мне не понятно где возникает объект Result , если я вижу код правильно то этот объект возникает ниже
Код:
typedef Typelist<T1, Tail> Result;
получается своего рода замкнутая схема где Result возникает внутри MakeList да ещё и при этом Tail формируется на основании
Код:
typedef typename MakeList< T2, T3, T4, T5 >::Result
Loksiin12 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Разобраться с кодом Boris2 Помощь студентам 1 15.07.2013 15:58
С++ разобраться с кодом marina12 Помощь студентам 2 21.05.2013 23:22
разобраться с кодом iris_ka Помощь студентам 0 16.05.2012 17:19
Разобраться с кодом. Vlero PHP 2 20.01.2011 12:46
проблемка с кодом, результат получается немного не такой как надо hen Помощь студентам 3 24.04.2009 15:11