Aka Tuple
От: Alexey Chen Чили  
Дата: 21.06.05 14:37
Оценка: 149 (15)
Заглянул тут в книжку Вандервурда. Там в главе про Tupple, штука такая есть — val<n>. Удобно конечно, но у меня возникла идея, возможно старая как мир. Но таки приведу её на правах прикола.


#include <string>
#include <iostream>

enum _n_Height  { n_Height };
enum _n_Weight  { n_Weight };
enum _n_Name    { n_Name };

struct Fake_Struct { void operator []( Fake_Struct const& ); };

template < class _Tx, class _Name, class _Super = Fake_Struct >
  struct Struct : _Super
    {
      using _Super::operator[];

      _Tx val_;
      _Tx& operator []( _Name n ) { return val_; }

      Struct() : val_(_Tx()) {}
    };

typedef 
  Struct< int, _n_Height, Struct < float, _n_Weight, Struct < std::string, _n_Name > > >
  MyStruct;


int main()
  {

    MyStruct s;

    s[n_Height]  = 10;
    s[n_Weight]  = 20.3;
    s[n_Name]    = "name";

    std::cout
      << s[n_Height]  << std::endl
      << s[n_Weight]  << std::endl
      << s[n_Name]    << std::endl
      ;

    return 0;

  }


PS:
Выкриков — 'баян' и тухлых помидоров я не боюсь, ибо действительно прикольно.
Re: Aka Tuple
От: Alexey Chen Чили  
Дата: 25.06.05 17:21
Оценка: 54 (4)
Здравствуйте, Alexey Chen, Вы писали:

AC>Заглянул тут в книжку Вандервурда. Там в главе про Tuple, штука такая есть — val<n>. Удобно конечно, но у меня возникла идея, возможно старая как мир. Но таки приведу её на правах прикола.


Я так понял, идея понравилась.

Тогда расскажу продолжение истории...

Кода я попробывал скомпилировать пример в шестой студии, получил весьма неприятное сообщение. Дескать, опреатор [] уже определён. Так пришлось отказатьса от using'а.

Но как же разрешить такую проблему, спросил я себя: Использовать опреаторы базовых шаблонных классов я не могу ибо компилятор их не видит, использовать явное указание компилятору я тоже не могу, он этого не понимает.

Однако, надо писать шаблонный оператор. Оператор, который будет в зависимости от ключа возвращать значение из нужной базы. Ну вы уже понимаете на какую фичу C++ я наткнулся? Правильно, у любой функции обязятельно должн быть задан тип для возвращаемого значения. Автоопределения типа по выраженияю в С++ нет.

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

Вот теперь мне стало действительно весело. Нужно было кардинально другое решение, и я его таки родил.

int main()
  {
    Scord< _sf_iHeight, Scord<_sf_fWeight, Scord<_sf_szName> > > s;

    sf_iHeight[s] = 10;
    sf_fWeight[s] = 20.3;
    sf_szName[s] = "jony";

    std::cout
      << sf_iHeight[s]  << std::endl
      << sf_fWeight[s]  << std::endl
      << sf_szName[s]   << std::endl
      << std::endl
      ;
 
    return 0;
  }


Идея вобщем-то простая — пеменять ключ и контейнер местами. Но таки _идея_! Возможно кому-то она поможет выкрабкаться из более тяжёлой ситуации. Чем то это похоже на функции селекторы, но принципиальное отличие в структуре, кторую можно рефлексировать.

Собственно реализация для тех кому интересно. ИМХО, имеет чисто академический интерес.
#define TEGGO_SFIELD(name,type) \
  struct _sf_##name : Sfield< type, _sf_##name > {}; \
  /*static*/ _sf_##name const sf_##name = _sf_##name()

template < class _Key >
  struct _Scord_Value
    {
      typename _Key::_Type sf_value_;
      _Scord_Value() : sf_value_(typename _Key::_Type()) {}
    };

template < class _Tp, class _Self >
  struct Sfield
    {
      typedef _Tp _Type;
      template < class _Value >
        _Type& operator[](_Value &val) const
        {
          return static_cast<_Scord_Value<_Self>&>(val).sf_value_;
        };
    };

struct _Scord_Fake {};

template < class _Key, class _Lst = _Scord_Fake >
  struct Scord : _Scord_Value<_Key>, _Lst 
    {
    };

TEGGO_SFIELD(iHeight, int);
TEGGO_SFIELD(fWeight, float);
TEGGO_SFIELD(szName,  std::string);
Re: Aka Tuple
От: MaximE Великобритания  
Дата: 26.06.05 16:31
Оценка: 9 (1) +5 -2
On Tue, 21 Jun 2005 18:37:02 +0400, Alexey Chen <17658@users.rsdn.ru> wrote:

> Заглянул тут в книжку Вандервурда. Там в главе про Tupple, штука такая есть — val<n>. Удобно конечно, но у меня возникла идея, возможно старая как мир. Но таки приведу её на правах прикола.

>
>
>
> #include <string>
> #include <iostream>
>
> enum _n_Height  { n_Height };
> enum _n_Weight  { n_Weight };
> enum _n_Name    { n_Name };
>
> struct Fake_Struct { void operator []( Fake_Struct const& ); };
>
> template < class _Tx, class _Name, class _Super = Fake_Struct >
>   struct Struct : _Super
>     {
>       using _Super::operator[];
>
>       _Tx val_;
>       _Tx& operator []( _Name n ) { return val_; }
>
>       Struct() : val_(_Tx()) {}
>     };
>
> typedef
>   Struct< int, _n_Height, Struct < float, _n_Weight, Struct < std::string, _n_Name > > >
>   MyStruct;
>
>
> int main()
>   {
>
>     MyStruct s;
>
>     s[n_Height]  = 10;
>     s[n_Weight]  = 20.3;
>     s[n_Name]    = "name";
>
>     std::cout
>       << s[n_Height]  << std::endl
>       << s[n_Weight]  << std::endl
>       << s[n_Name]    << std::endl
>       ;
>
>     return 0;
>
>   }
>

>
> PS:
> Выкриков — 'баян' и тухлых помидоров я не боюсь, ибо действительно прикольно.

Возможно это "действительно прикольно", но абсолютно бесполезно.

Проблем с этим tuple'ом две:
  1. Сам факт, что до объявления кортежа нужно объявить имена его членов, а при объявлении объявить имена и их типы убивают всю идею на корню. Я не вижу, чем приведенный выше кортеж лучше, чем обычное
    struct my_struct
    {
         int height;
         float weight;
         std::string name;
    };

    Я вижу лишь что на описание этой же структуры в оригинальном коде ушло больше писанины без какой либо пользы.
  2. Практическая применимость такого кортежа в шаблонном коде близка к абсолютному нулю. Ничего не стоит в compile time определить количество членов boost::tuple и проитерироваться по его членам, так как индексом его членов является целое, результаты арифметических операций над которым вычисляются в compile time. По приведенному кортежу невозможно проитерироваться в generic коде, так как нужно знать имена членов. Возвращемся к тому, что индексы должны быть простыми целыми.
    С другой стороны целочисленные индексы не убивают возможности использовать осмысленные имена. boost::tuple:
    typedef tuple<int, float, std::string> my_struct;
    enum { height, weight, name };
    // ...
    my_struct s;
    get<height>(s) = 1;

    Я не вижу недостатка в том, что вместо operator[] для доступа к членам используется get<>(), так как реально никакого практического смыла в operator[] нет из-за того, что он не может использоваться в generic коде который ожидает семантику operator[] как у встроенных типов.

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[2]: Aka Tuple
От: Alexey Chen Чили  
Дата: 26.06.05 17:19
Оценка: +1 -1
Здравствуйте, MaximE, Вы писали:

ME>Я вижу лишь что на описание этой же структуры в оригинальном коде ушло больше писанины без какой либо пользы.

ME>
  • Практическая применимость такого кортежа в шаблонном коде близка к абсолютному нулю. Ничего не стоит в compile time определить количество членов boost::tuple и проитерироваться по его членам, так как индексом его членов является целое, результаты арифметических операций над которым вычисляются в compile time. По приведенному кортежу невозможно проитерироваться в generic коде, так как нужно знать имена членов. Возвращемся к тому, что индексы должны быть простыми целыми.

    Не буду спорить. Просто спрошу: что если я решал другую задачу, о которой Вы даже не подумали? Что если 'обобщённый код' не всегда совпадает с Modern C++ и метопрограммирование? Возможно есть и другие способы написания программ кроме как boost::... Наверное, но науке это, как водится, не известно.

    Однако сей вопрос к топику дела не имеет. Имеет дело другой. Вы всегда пишете только практически применимый самодостаточный неизбыточный код, максимально эффективно решающий задачу? Ответ можно в топик про то кто такие кодеры.

    Это была идея. Просто идея описания структуры в читабельном виде с возможностью рефлексии. Но не для использования_каждым_пионером_в_любом_месте_в_которое_он_только_сможет_это_воткнуть. Лично я рассматриваю такие вещи как искусство. Как на это смотреть другим, это их дело. _Мне_ нравится.

    Где и зачем может понадобиться такой приём я не буду расписывать, это уже специфика. Специфика же порождает непонимание людей не сталкивавшихся с ней. ИМХО, кому надо сам поймёт нужен ему такой приём или нет, я же просто поделился идеей. Лично вам идея не понравилась? Ну и ладно.
  • Re[3]: Aka Tuple
    От: Pavel Chikulaev Россия  
    Дата: 26.06.05 17:48
    Оценка: +1 -1
    Здравствуйте, Alexey Chen, Вы писали:

    AC>Не буду спорить. Просто спрошу: что если я решал другую задачу, о которой Вы даже не подумали?

    И что за задача? Она правда не решается с помощью boost.tuples? Не верю.

    AC>Что если 'обобщённый код' не всегда совпадает с Modern C++ и метопрограммирование? Возможно есть и другие способы написания программ кроме как boost::... Наверное, но науке это, как водится, не известно.

    Способы безусловно есть, но согласись boost удобней. Если сделаешь лучше — круто — но пока я не вижу, что это у тебя получилось.

    AC>Однако сей вопрос к топику дела не имеет. Имеет дело другой. Вы всегда пишете только практически применимый самодостаточный неизбыточный код, максимально эффективно решающий задачу? Ответ можно в топик про то кто такие кодеры.

    Извини конечно, но смысла я вообще не вижу в твоем коде, я могу получить то же самое с более c удобным синтаксисом и гораздо более простым повторным использованием (boost::tuples).

    AC>Это была идея. Просто идея описания структуры в читабельном? виде с возможностью рефлексии. Но не для использования_каждым_пионером_в_любом_месте_в_которое_он_только_сможет_это_воткнуть.

    AC>Лично я рассматриваю такие вещи как искусство.
    Искусство лишь тогда когда есть смысл и удобный синтаксис, здесь я его не вижу, а вот то, как написаны boost::tuples и boost::bind — это уже искусство и какой сделать такой syntactic sugar для пользователя.

    AC>Как на это смотреть другим, это их дело. _Мне_ нравится.

    Эт пожалуйста. Но лично я согласен с Максимом на 100%.

    AC>Где и зачем может понадобиться такой приём я не буду расписывать, это уже специфика. Специфика же порождает непонимание людей не сталкивавшихся с ней. ИМХО, кому надо сам поймёт нужен ему такой приём или нет, я же просто поделился идеей.

    Да нигде не понадобится. И синтаксис хромает, и удобство, да и смысла мало...

    Извини если что это все имхо, но в некоторых местах достаточно объективное...
    Re[4]: Aka Tuple
    От: Alexey Chen Чили  
    Дата: 26.06.05 19:39
    Оценка:
    Здравствуйте, Pavel Chikulaev, Вы писали:

    AC>>Не буду спорить. Просто спрошу: что если я решал другую задачу, о которой Вы даже не подумали?

    PC>И что за задача? Она правда не решается с помощью boost.tuples? Не верю.
    Твоё право. Но я не буду постить здесь кода больше чем на экран. И ни кому ни чего доказывать тоже не буду. Я не для для сюда пришёл. А делать же лучше, круче, моднее... длиной без меня пожалуйста мерейтесь. Я всего лишь показал интересную _на_мой_ взгляд идею. Ты считаешь что это бред. Пожалуйста, и разубеждать тебя в этом я не буду. Зачем мне это? Будем считать что ты прав, и меня после пива в голове помутнение возникло, захотелось чегой-то изобразить. Пускай для тебя это будет обьяснением моей задачи. Ок?

    PC>Извини конечно, но смысла я вообще не вижу в твоем коде, я могу получить то же самое с более c удобным синтаксисом и гораздо более простым повторным использованием (boost::tuples).

    Дык, уже как-то пытался обьяснить что 'смысла я вообще не вижу' и 'вижу что смысла вообще нет' не одно и то же. Но прекратил попытки это делать. Бесполезное занятие.

    PC>Извини если что это все имхо, но в некоторых местах достаточно объективное...

    Дык, это публичный форум. Здесь любое мнение 'обьективное'
    Re[3]: Aka Tuple
    От: MaximE Великобритания  
    Дата: 26.06.05 19:40
    Оценка: -1
    On Sun, 26 Jun 2005 21:19:54 +0400, Alexey Chen <17658@users.rsdn.ru> wrote:

    []

    > Не буду спорить.


    Спорить нам не нужно. Приведи конкретные преимущества твоей идеи на конкретном реальном примере.

    > Просто спрошу: что если я решал другую задачу, о которой Вы даже не подумали? Что если 'обобщённый код' не всегда совпадает с Modern C++ и метопрограммирование? Возможно есть и другие способы написания программ кроме как boost::... Наверное, но науке это, как водится, не известно.


    Нам, простым смертным кодерам, не терпится достигнуть просветления и узнать ту высокую задачу, которую хранит твое чело. (прости, — не совершенен, не удержался )

    > Однако сей вопрос к топику дела не имеет. Имеет дело другой. Вы всегда пишете только практически применимый самодостаточный неизбыточный код, максимально эффективно решающий задачу? Ответ можно в топик про то кто такие кодеры.


    Последнее время — да, screw genericity. Следующая философия мне близка http://www.faqs.org/docs/artu/ch01s06.html

    > Это была идея. Просто идея описания структуры в читабельном виде с возможностью рефлексии. Но не для использования_каждым_пионером_в_любом_месте_в_которое_он_только_сможет_это_воткнуть. Лично я рассматриваю такие вещи как искусство. Как на это смотреть другим, это их дело. _Мне_ нравится.

    >
    > Где и зачем может понадобиться такой приём я не буду расписывать, это уже специфика. Специфика же порождает непонимание людей не сталкивавшихся с ней. ИМХО, кому надо сам поймёт нужен ему такой приём или нет, я же просто поделился идеей. Лично вам идея не понравилась? Ну и ладно.

    Еще раз попрошу конкретный пример, а не нытье про хрупкую душу художника, которую не просто понять. Мы — инженеры, форум технический, поэтому best ideas only.

    --
    Maxim Yegorushkin
    Posted via RSDN NNTP Server 1.9
    Re[4]: Aka Tuple
    От: Alexey Chen Чили  
    Дата: 26.06.05 20:04
    Оценка: +1 :))
    Здравствуйте, MaximE, Вы писали:

    ME>On Sun, 26 Jun 2005 21:19:54 +0400, Alexey Chen <17658@users.rsdn.ru> wrote:


    >> Не буду спорить.

    ME>Спорить нам не нужно. Приведи конкретные преимущества твоей идеи на конкретном реальном примере.

    Простите, приемущества перед чем? Я где-то написал что вот дескать придумал нечто супер крутое, которое порвет (ну например) boost как тузик грелку? Может я сказал что написал мега tuple и всем три раза сказать ку? Я поделился идей, почему я ещё должен кому-то доказывать, что эта стоящая идея?! НЕ БУДУ этого делать! В принципе.

    Не понял ты зачем это надо, ну дык, а я то тут при чём?
    Я уже привёл пример задачи вашему единомышленнику, повторяться не буду.

    AC> Просто спрошу: что если я решал другую задачу, о которой Вы даже не подумали? Что если 'обобщённый код' не всегда совпадает с Modern C++ и метопрограммирование? Возможно есть и другие способы написания программ кроме как boost::... Наверное, но науке это, как водится, не известно.

    ME>Нам, простым смертным кодерам, не терпится достигнуть просветления и узнать ту высокую задачу, которую хранит твое чело. (прости, — не совершенен, не удержался )
    А я и не сомневался

    *в сторону* нда, я на личности не переходил.

    Может повесим на входе табличку:


    Каждый желающий запостить идею или пример кода должен приложить подробно разжёванное описание (понятное для кофейников), а так же примеры на которых доступно показано чем его идея лучше чем boost. Примеры должны быть написаны в терминах буста с использованием буста и на задачах решаемых бустом. Отсутствие буста в примерах и идее, а так же непонимание почитателями буста, почему таковое кому либо может быть интересно, карается всеобщем порицанием и удалением.


    А? Как тебе такая идея? Тогда я точно постить ничего не буду. И тебе будет сухо и комфортно.
    (Особенно в духе идей об общем уровне форума)

    Можно ещё переименовать форум из C++ в BOOST++, тогда наверное наступит всеобщее счастье и просветление.
    Re: Aka Tuple
    От: Alexey Chen Чили  
    Дата: 26.06.05 20:59
    Оценка:
    Здравствуйте, Alexey Chen, Вы писали:

    AC>Заглянул тут в книжку Вандервурда. Там в главе про Tupple, штука такая есть — val<n>. Удобно конечно, но у меня возникла идея, возможно старая как мир. Но таки приведу её на правах прикола.


    Я так понял по откликам мастеров пера, что надо обьяснить суть идеи.

    Суть проста. Использовать для индексирования полей структуры типы. В отличии от кортежа, который я упомянул в начале топика, такой подход имеет смысл для создания метаинформации о структуре при сохранении естественного доступа к её (структуры) элементам. И, что важно, не отменяет возможности доступа по номеру. Иначе говоря это тот же tuple, но с хуманридабл тегами.

    Это позволяет писать понятный код и с минимальными усилиями реализовывать например сериализацию.

    Был приведён такой пример
    typedef tuple<int, float, std::string> my_struct;
    enum { height, weight, name };
    // ...
    my_struct s;
    get<height>(s) = 1;

    Да конечно можно и так, только это совсем не то. Да и ещё надо не забыть поддерживать соответствие перечисления и кортежа.

    Второй пример — это адаптация под примитивный компилятор. Но суть идеи не в самой адаптации, а в приёме который для этого использован. Кстати, сам код может также подтолкнуть к некоторым интересным идеям, но уже архитектурным.
    Re[5]: Aka Tuple
    От: MaximE Великобритания  
    Дата: 26.06.05 22:07
    Оценка:
    On Mon, 27 Jun 2005 00:04:21 +0400, Alexey Chen <17658@users.rsdn.ru> wrote:

    > ME>Спорить нам не нужно. Приведи конкретные преимущества твоей идеи на конкретном реальном примере.

    >
    > Простите, приемущества перед чем?

    Перед обыкновенной структурой.

    --
    Maxim Yegorushkin
    Posted via RSDN NNTP Server 1.9
    Re[6]: Aka Tuple
    От: Alexey Chen Чили  
    Дата: 26.06.05 22:22
    Оценка: +1
    Здравствуйте, MaximE, Вы писали:

    >> Простите, приемущества перед чем?

    ME>Перед обыкновенной структурой.

    Ах, Вы про это. Наверное надо было явно упомянуть, что данный приём позволяет перебрать все поля ака tuple при этом сохраняет читабельность структуры и допускает определение метаинформации для реализации рефлекшина. Такого обьяснения достаточно или надо подробнее?

    Извините, что написал только идею, надо наверное было писать много много кода, чтобы идеи было не видно, но зато было много неймспейсов, шаблонов и макросов. Как я посмотрю нынче это очень популярный способ изложения.
    Re[4]: Aka Tuple
    От: eao197 Беларусь http://eao197.blogspot.com
    Дата: 27.06.05 04:25
    Оценка: +3
    Здравствуйте, MaximE, Вы писали:

    ME>On Sun, 26 Jun 2005 21:19:54 +0400, Alexey Chen <17658@users.rsdn.ru> wrote:


    ME>[]


    >> Не буду спорить.


    ME>Спорить нам не нужно. Приведи конкретные преимущества твоей идеи на конкретном реальном примере.


    Извините, коллеги, что вмешиваюсь в ваш холивар, но мне показалось (на первый взгляд, я не проверял на компиляторе), что в решении Alexey Chen
    Автор: Alexey Chen
    Дата: 21.06.05
    можно использовать не последовательно идущие значения enum-a. Например:
    enum stop_t  { cmd_stop = 0x1001 };
    enum start_t { cmd_start = 0x2000 };
    enum pause_t { cmd_pause = 0x40000 };

    (такие значения могут потребоваться, например, для управления каким-то внешним устройством).

    В то время как в boost::tuple необходимо использовать значения от 0 до k-1:

    get<N>(t)

    where t is a tuple object and N is a constant integral expression specifying the index of the element to be accessed. Depending on whether t is const or not, get returns the Nth element as a reference to const or non-const type. The index of the first element is 0 and thus N must be between 0 and k-1, where k is the number of elements in the tuple. Violations of these constrains are detected at compile time.




    А вообще, по количеству упоминаний boost-а в данном форуме, слова Алексея (Re[4]: Aka Tuple
    Автор: Alexey Chen
    Дата: 27.06.05
    ):

    Каждый желающий запостить идею или пример кода должен приложить подробно разжёванное описание (понятное для кофейников), а так же примеры на которых доступно показано чем его идея лучше чем boost. Примеры должны быть написаны в терминах буста с использованием буста и на задачах решаемых бустом. Отсутствие буста в примерах и идее, а так же непонимание почитателями буста, почему таковое кому либо может быть интересно, карается всеобщем порицанием и удалением.

    Оказываются довольно актуальными
    Все же boost пока не стандарт, не везде работает, да и могут быть административно/политические причины не использовать boost. Поэтому я не думаю, что нужно обязательно при публикации какой-то идеи проводить ее сравние с boost-ом. А то это начинает напоминать проверки на соответствие "генеральной линии партии и коммунистической идеологии" в недавние времена
    ... << RSDN@Home 1.1.4 beta 7 rev. 447>>


    SObjectizer: <микро>Агентно-ориентированное программирование на C++.
    Re[7]: Aka Tuple
    От: MaximE Великобритания  
    Дата: 27.06.05 05:41
    Оценка:
    On Mon, 27 Jun 2005 02:22:58 +0400, Alexey Chen <17658@users.rsdn.ru> wrote:

    >>> Простите, приемущества перед чем?

    > ME>Перед обыкновенной структурой.
    >
    > Ах, Вы про это. Наверное надо было явно упомянуть, что данный приём позволяет перебрать все поля ака tuple при этом сохраняет читабельность структуры и допускает определение метаинформации для реализации рефлекшина. Такого обьяснения достаточно или надо подробнее?

    Недостаточно. Напиши, пожалуйста, шаблон ф-ции, которая будет итерироваться по членам твоего кортежа (такая ф-ция необходима для реализации упомянутого тобой рефлекшена).

    --
    Maxim Yegorushkin
    Posted via RSDN NNTP Server 1.9
    Re[5]: Aka Tuple
    От: MaximE Великобритания  
    Дата: 27.06.05 05:49
    Оценка:
    On Mon, 27 Jun 2005 08:25:46 +0400, eao197 <31476@users.rsdn.ru> wrote:

    []

    > Извините, коллеги, что вмешиваюсь в ваш холивар, но мне показалось (на первый взгляд, я не проверял на компиляторе), что в решении Alexey Chen
    Автор: Alexey Chen
    Дата: 21.06.05
    можно использовать не последовательно идущие значения enum-a. Например:

    >
    > enum stop_t  { cmd_stop = 0x1001 };
    > enum start_t { cmd_start = 0x2000 };
    > enum pause_t { cmd_pause = 0x40000 };
    >

    > (такие значения могут потребоваться, например, для управления каким-то внешним устройством).
    >
    > В то время как в boost::tuple необходимо использовать значения от 0 до k-1:

    Не вижу как эту возможность иожно применить на практике.

    >

    > А вообще, по количеству упоминаний boost-а в данном форуме, слова Алексея (Re[4]: Aka Tuple
    Автор: Alexey Chen
    Дата: 27.06.05
    ):


    []

    > Все же boost пока не стандарт, не везде работает, да и могут быть административно/политические причины не использовать boost. Поэтому я не думаю, что нужно обязательно при публикации какой-то идеи проводить ее сравние с boost-ом. А то это начинает напоминать проверки на соответствие "генеральной линии партии и коммунистической идеологии" в недавние времена


    Я хочу лишь один малюсенький пример реального кода, где такой кортеж решает задачу лучше, чем обыкновенная структура или boost::tuple. Сранение с boost'ом пришлось потому, что там тоже есть кортеж, доступ к элементам которого, в отличие от приведенного кортежа, можно осуществить в generic коде.

    --
    Maxim Yegorushkin
    Posted via RSDN NNTP Server 1.9
    Re[2]: Aka Tuple
    От: Pavel Chikulaev Россия  
    Дата: 27.06.05 05:53
    Оценка:
    Здравствуйте, Alexey Chen, Вы писали:

    AC>Здравствуйте, Alexey Chen, Вы писали:


    AC>>Заглянул тут в книжку Вандервурда. Там в главе про Tupple, штука такая есть — val<n>. Удобно конечно, но у меня возникла идея, возможно старая как мир. Но таки приведу её на правах прикола.

    См. Александреску, а потом boost::tuples, а потом boost::mpl...

    AC>Я так понял по откликам мастеров пера, что надо обьяснить суть идеи.


    AC>Суть проста. Использовать для индексирования полей структуры типы. В отличии от кортежа, который я упомянул в начале топика, такой подход имеет смысл для создания метаинформации о структуре при сохранении естественного доступа к её (структуры) элементам. И, что важно, не отменяет возможности доступа по номеру. Иначе говоря это тот же tuple, но с хуманридабл тегами.


    Немного погодя покажу код, позволяющий делать следующее:
    class name_t   {};
    class number_t {};
    tagged_tuple<std::string, name_t, int, number_t> s;
    s.get<name_t>() = "hello world";
    s.get<number_t>() = 2005;
    assert(s.get<0>() == s.get<name_t>());
    assert(s.get<1>() == s.get<number_t>());

    О пользователе надо заботится

    AC>Это позволяет писать понятный код и с минимальными усилиями реализовывать например сериализацию.

    Да ты что!
    Ты наверно просто не в курсе:
    boost::tuple<std::string, int> s;
    cin  >> s;
    cout << s;


    AC>Второй пример — это адаптация под примитивный компилятор. Но суть идеи не в самой адаптации, а в приёме который для этого использован. Кстати, сам код может также подтолкнуть к некоторым интересным идеям, но уже архитектурным.

    boost::tuples сделает твой пример по переносимости так что про это даже не вспоминай. Какие идеи? В компил-тайм длину посчитать или перевернуть список типов?
    Re[6]: Aka Tuple
    От: eao197 Беларусь http://eao197.blogspot.com
    Дата: 27.06.05 06:05
    Оценка: +1
    Здравствуйте, MaximE, Вы писали:

    ME>On Mon, 27 Jun 2005 08:25:46 +0400, eao197 <31476@users.rsdn.ru> wrote:


    ME>[]


    >> Извините, коллеги, что вмешиваюсь в ваш холивар, но мне показалось (на первый взгляд, я не проверял на компиляторе), что в решении Alexey Chen
    Автор: Alexey Chen
    Дата: 21.06.05
    можно использовать не последовательно идущие значения enum-a. Например:

    >>
    >> enum stop_t  { cmd_stop = 0x1001 };
    >> enum start_t { cmd_start = 0x2000 };
    >> enum pause_t { cmd_pause = 0x40000 };
    >>

    >> (такие значения могут потребоваться, например, для управления каким-то внешним устройством).
    >>
    >> В то время как в boost::tuple необходимо использовать значения от 0 до k-1:

    ME>Не вижу как эту возможность иожно применить на практике.


    Ну, применить на практике и найти случай, когда boost::tuple не будет работать, это немного разные вещи. Имхо, я показал enum-ы, которые нельзя использовать для доступа к элементами boost::tuple.

    >>

    >> А вообще, по количеству упоминаний boost-а в данном форуме, слова Алексея (Re[4]: Aka Tuple
    Автор: Alexey Chen
    Дата: 27.06.05
    ):


    ME>[]


    >> Все же boost пока не стандарт, не везде работает, да и могут быть административно/политические причины не использовать boost. Поэтому я не думаю, что нужно обязательно при публикации какой-то идеи проводить ее сравние с boost-ом. А то это начинает напоминать проверки на соответствие "генеральной линии партии и коммунистической идеологии" в недавние времена


    ME>Я хочу лишь один малюсенький пример реального кода, где такой кортеж решает задачу лучше, чем обыкновенная структура или boost::tuple. Сранение с boost'ом пришлось потому, что там тоже есть кортеж, доступ к элементам которого, в отличие от приведенного кортежа, можно осуществить в generic коде.


    А я думаю, что подобный пример следует требовать в случае, когда автор идеи начинает пропагандировать ее и навязывать вместо boost/ace/stlsoft/whatever. Здесь же, имхо, такого нет.
    ... << RSDN@Home 1.1.4 beta 7 rev. 447>>


    SObjectizer: <микро>Агентно-ориентированное программирование на C++.
    Re[2]: Aka Tuple
    От: uw  
    Дата: 27.06.05 07:22
    Оценка: 10 (2)
    Здравствуйте, MaximE, Вы писали:

    ME>
  • Сам факт, что до объявления кортежа нужно объявить имена его членов, а при объявлении объявить имена и их типы убивают всю идею на корню. Я не вижу, чем приведенный выше кортеж лучше, чем обычное
    ME>
    ME>struct my_struct
    ME> ...
    ME>


    +1

    Но с другой стороны Alexey Chen просто ошибся, назвав это tuple. Это конечно не кортеж, это именно структура.

    ME>Я вижу лишь что на описание этой же структуры в оригинальном коде ушло больше писанины без какой либо пользы.

    ME>
  • Практическая применимость такого кортежа в шаблонном коде близка к абсолютному нулю. Ничего не стоит в compile time определить количество членов boost::tuple и проитерироваться по его членам, так как индексом его членов является целое, результаты арифметических операций над которым вычисляются в compile time. По приведенному кортежу невозможно проитерироваться в generic коде, так как нужно знать имена членов. Возвращемся к тому, что индексы должны быть простыми целыми.

    Бред. Или я чего то не понимаю, или это типичный симптом пользователя буста(судя по количеству согласившихся). В данном случае можно спокойно обращаться к членам структуры по индексу, выяснять их количество, итерироваться в compile time. Я потратил ровно две минуты, чтобы написать такой код:

    #include <string>
    #include <iostream>
    #include <typeinfo>
    
    enum _n_Height  { n_Height };
    enum _n_Weight  { n_Weight };
    enum _n_Name    { n_Name };
    
    struct Fake_Struct { void operator []( Fake_Struct const& ); };
    
    template < class _Tx, class _Name, class _Super = Fake_Struct >
      struct Struct : _Super
        {
          using _Super::operator[];
    
          _Tx val_;
          _Tx& operator []( _Name n ) { return val_; }
    
          Struct() : val_(_Tx()) {}
        };
    
    typedef 
      Struct< int, _n_Height, Struct < float, _n_Weight, Struct < std::string, _n_Name > > >
      MyStruct;
    
    template <class T>
    struct tuple_iterate
    {
    };
    
    template <class T, class Y, class S>
    struct tuple_iterate<Struct<T, Y, S> >
    {
        static void eval()
        {
            std::cout << typeid(T).name() <<  " " << typeid(Y).name() << std::endl;
            tuple_iterate<S>::eval();
        }
    };
    
    template <class T, class Y>
    struct tuple_iterate<Struct<T, Y, Fake_Struct> >
    {
        static void eval()
        {
            std::cout << typeid(T).name() <<  " " << typeid(Y).name() << std::endl;
        }
    };
    
    int main()
    {
        MyStruct s;
    
        s[n_Height]  = 10;
        s[n_Weight]  = 20.3;
        s[n_Name]    = "name";
    
        std::cout << s[n_Height]  << std::endl << s[n_Weight]  << std::endl << s[n_Name]    << std::endl;
        tuple_iterate<MyStruct>::eval();
        return 0;
    }
  • Re[3]: Aka Tuple
    От: Pavel Chikulaev Россия  
    Дата: 27.06.05 09:15
    Оценка: 1 (1)
    Здравствуйте, Pavel Chikulaev, Вы писали:

    PC>Немного погодя покажу код, позволяющий делать следующее:

    Показываю Copyright мой. Не отвечаю за последствия от увиденного. Нервных прошу воздержаться от просмотра Работает на VC7.1 и VC8
    #include <boost/tuple/tuple.hpp>
    #include <boost/tuple/tuple_io.hpp>
    #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
    #include <boost/preprocessor/arithmetic/mul.hpp>
    #include <boost/preprocessor/punctuation/comma_if.hpp>
    #include <boost/utility/enable_if.hpp>
    #include <boost/mpl/vector.hpp>
    #include <boost/mpl/find.hpp>
    #include <boost/mpl/unique.hpp>
    #include <boost/mpl/size.hpp>
    #include <Boost/mpl/at.hpp>
    #include <boost/type_traits/is_same.hpp>
    #include <string>
    #include <iostream>
    
    #ifndef FAKIE_TAGGED_TUPLE_MAX_ARITY
    # define FAKIE_TAGGED_TUPLE_MAX_ARITY 10
    #elif FAKIE_TAGGED_TUPLE_MAX_ARITY > 10
    #error boost::tuples doesn't support arity > 10
    #endif
    
    namespace fakie
    {
        template<typename Types, typename Names, typename Base>
        struct tagged_tuple_detail 
            : virtual Base
            , boost::enable_if_c<boost::mpl::size<Types>::type::value == boost::mpl::size<Names>::type::value>
            , boost::enable_if<boost::is_same<boost::mpl::unique<Types>, Types> >
        {
            using Base::get;
    
            template<typename T>
            typename boost::tuples::access_traits<
                typename boost::mpl::at_c<
                    Types, 
                    boost::mpl::find<Names, T>::type::pos::value
                >::type
            >::non_const_type get ()
            {
                return boost::tuples::get<boost::mpl::find<Names, T>::type::pos::value>(*this);
            }
    
            template<typename T>
            typename boost::tuples::access_traits<
                typename boost::mpl::at_c<
                    Types, 
                    boost::mpl::find<Names, T>::type::pos::value
                >::type
            >::const_type get () const
            {
                return boost::tuples::get<boost::mpl::find<Names, T>::type::pos::value>(*this);
            }
        };
    
    #define FAKIE_TAGGED_TUPLE_DETAIL_TYPES(z, n, text)\
        BOOST_PP_COMMA_IF(n) BOOST_PP_CAT(text, BOOST_PP_MUL(2, n))
    
    #define FAKIE_TAGGED_TUPLE_DETAIL_VALUES(z, n, text)\
        BOOST_PP_COMMA_IF(n) BOOST_PP_CAT(text, BOOST_PP_ADD(BOOST_PP_MUL(2, n), 1))
    
    #define FAKIE_TAGGED_TUPLE_DETAIL_MPL_2_TUPLE(z, n, text)\
        BOOST_PP_COMMA_IF(n)\
        typename boost::mpl::if_<\
            boost::is_same<BOOST_PP_CAT(text, BOOST_PP_MUL(2, n)), boost::mpl::na>,\
            boost::tuples::null_type,\
            BOOST_PP_CAT(text, BOOST_PP_MUL(2, n))\
        >::type
    
        template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PP_MUL(2, FAKIE_TAGGED_TUPLE_MAX_ARITY), typename T, boost::mpl::na)>
        struct tagged_tuple
            : tagged_tuple_detail
            <
                boost::mpl::vector<BOOST_PP_REPEAT(FAKIE_TAGGED_TUPLE_MAX_ARITY, FAKIE_TAGGED_TUPLE_DETAIL_TYPES, T)>,
                boost::mpl::vector<BOOST_PP_REPEAT(FAKIE_TAGGED_TUPLE_MAX_ARITY, FAKIE_TAGGED_TUPLE_DETAIL_VALUES, T)>,
                boost::tuple<BOOST_PP_REPEAT(FAKIE_TAGGED_TUPLE_MAX_ARITY, FAKIE_TAGGED_TUPLE_DETAIL_MPL_2_TUPLE, T)>
            >
        {
        };
    
    #undef FAKIE_TAGGED_TUPLE_DETAIL_TYPES
    #undef FAKIE_TAGGED_TUPLE_DETAIL_VALUES
    #undef FAKIE_TAGGED_TUPLE_DETAIL_MPL_2_TUPLE
    }
    
    class name_t {};
    class value_t {};
    class weight_t {};
    
    int main()
    {
        using namespace fakie;
    
        tagged_tuple<std::string, name_t, int, value_t, double, weight_t> s;
        
        s.get<name_t>()   = "Hello World";
        s.get<value_t>()  = 2005;
        s.get<weight_t>() = 2.34543;
    
        std::cout << s;
    
        return k;
    }
    Re[6]: Aka Tuple
    От: Alexey Chen Чили  
    Дата: 27.06.05 09:25
    Оценка:
    Здравствуйте, MaximE, Вы писали:

    ME>Я хочу лишь один малюсенький пример реального кода, где такой кортеж решает задачу лучше, чем обыкновенная структура или boost::tuple. Сранение с boost'ом пришлось потому, что там тоже есть кортеж, доступ к элементам которого, в отличие от приведенного кортежа, можно осуществить в generic коде.


    Код приводить не буду, он слишком большой и неинтересный. Конкретное применение — например, реализация SMPP протокола, представление PDU таким картежем.

    Вообще любое использование структуры которая нужна как человеку так и для предстваления в пакетном виде для передачи. При этом имеющая опциональные поля и транслируемая частично или полностью в из TLV.
    Re[7]: Aka Tuple
    От: eao197 Беларусь http://eao197.blogspot.com
    Дата: 27.06.05 09:46
    Оценка:
    Здравствуйте, Alexey Chen, Вы писали:

    AC>Здравствуйте, MaximE, Вы писали:


    ME>>Я хочу лишь один малюсенький пример реального кода, где такой кортеж решает задачу лучше, чем обыкновенная структура или boost::tuple. Сранение с boost'ом пришлось потому, что там тоже есть кортеж, доступ к элементам которого, в отличие от приведенного кортежа, можно осуществить в generic коде.


    AC>Код приводить не буду, он слишком большой и неинтересный. Конкретное применение — например, реализация SMPP протокола, представление PDU таким картежем.


    А вот с этого места, если можно, поподробнее.
    Ты вообще PDU хочешь представлять такими кортежами? Т.е. типа submit_sm, deliver_sm и т.д.?
    Или речь идет об optional TLV? Но ведь в одном только submit_sm этих TLV штук сорок (в smpp 5.0 я насчитал 44).
    ... << RSDN@Home 1.1.4 beta 7 rev. 447>>


    SObjectizer: <микро>Агентно-ориентированное программирование на C++.
    Подождите ...
    Wait...
    Пока на собственное сообщение не было ответов, его можно удалить.