пятница, 18 октября 2019 г.

[prog.c++] Почему C++ никому не нужен, но никуда не денется, на одном маленьком примере

Из свеженького:

template<
   template<classclass Container_Adaptor >
struct to_container_consumer_t : public consumer_tag
{
   templatetypename Container, typename Item >
   void
   consume( Container & to, Item && item )
   {
      Container_Adaptor<Container>::store( to, std::move(item) );
   }
};

Это шаблонный класс, который параметризуется другим шаблонным классом. И у которого всего один шаблонный метод, который параметризуется еще двумя типами.

Задача объекта этого шаблонного класса -- взять некое значение (не суть важно какое) и переместить его в некий контейнер (не суть важно какой). Как именно будет происходить перемещение to_container_consumer_t не знает. Он лишь знает, что это перемещение можно сделать посредством шаблонного параметра Container_Adaptor.

Насколько я понимаю (а понимаю не так, чтобы уж много), to_container_consumer_t -- это метафункция, которая параметризуется другой метафункцией. И в C++ это вот выражается вот таким вот образом.

Так вот, C++ не нужен в мейнстриме именно потому, что в нем можно выражать метафункции, параметризуемые другими метафункциями. А в мейнтриме это никому не нужно. Мягко говоря.

И C++ никуда не денется именно потому, что в нем можно выражать метафункции, параметризуемые другими метафункциями. Это в принципе мало кому нужно. Но, в принципе, нужно. И вот те, кому нужно, и будут продолжать использовать C++.

За последние 3-4 недели довелось поучаствовать в нескольких спорах на тему применимости C++ и востребованности/оправданности новых возможностей C++. И прочитать еще несколько таких споров. И вот что я думаю: C++ должен превратиться во что-то типа Хаскелля. Многие слышали о нем. Многие думают, что это круто и с его помощью можно творить разные крутые вещи. Многие считают, что это не язык для простых смертных. Но мало кто имеет реальное представление о нем. Еще меньше имеют возможность его применять. И еще меньше им владеют.

И, вообще-то говоря, превращение C++ во что-то типа Хаскелля с постепенным отходом от мейнстрима, пойдет на пользу всем. И C++. И тем, кто из него уйдет. И тем, кто в нем останется.

Так думаю на данный момент.

Под катом маленький пример того, как этот to_container_consumer_t используется. И несколько реализаций Container_Adaptor.

template< template<classclass Container_Adaptor = default_container_adaptor >
[[nodiscard]] auto to_container()
{
   return impl::to_container_consumer_t<Container_Adaptor>();
}
...
[[nodiscard]] auto try_parse( source_t & from )
{
   std::pair< bool, Container > result;

   result.first = sequence(
         repeat( 0, N, symbol(','), ows() ),
         m_element >> to_container(),  
         repeat( 0, N,
            ows(), symbol(','),
            maybe( ows(), m_element >> to_container() )
         )
      ).try_process( from, result.second );

   return result;
}

А вот реализации Container_Adaptor для разных случаев:

templatetypename T >
struct default_container_adaptor;

templatetypename T, typename... Args >
struct default_container_adaptor< std::vector< T, Args... > >
{
   using container_type = std::vector< T, Args... >;
   using value_type = typename container_type::value_type;

   static void
   store( container_type & to, value_type && what )
   {
      to.push_back( std::move(what) );
   }
};

templatetypename Char, typename... Args >
struct default_container_adaptor< std::basic_string< Char, Args... > >
{
   using container_type = std::basic_string< Char, Args... >;
   using value_type = Char;

   static void
   store( container_type & to, value_type && what )
   {
      to.push_back( what );
   }
};

templatetypename K, typename V, typename... Args >
struct default_container_adaptor< std::map< K, V, Args... > >
{
   using container_type = std::map< K, V, Args... >;
   // NOTE: we can't use container_type::value_type here
   // because value_type for std::map is std::pair<const K, V>,
   // not just std::pair<K, V>,
   using value_type = std::pair<K, V>;

   static void
   store( container_type & to, value_type && what )
   {
      to.emplace( std::move(what) );
   }
};

template<>
struct default_container_adaptor< nothing_t >
{
   using container_type = nothing_t;
   using value_type = nothing_t;

   static void
   store( container_type &, value_type && ) noexcept {}
};

6 комментариев:

Stanislav Mischenko комментирует...

На мой взгляд программисты делятся на две группы: те, кому нужен Go, и те, кому нужен Хаскель. И тем, и другим в С++ некомфортно.

eao197 комментирует...

@Stanislav Mischenko

Не понятно куда потерялись пользователи Fortran-а и Java. Ведь ни те, ни другие особо ни мечтают ни про Go, ни про Haskell.

Stanislav Mischenko комментирует...

Поясню. Я просто выбрал эти два языка программирования, как две стороны, в которую клонит программистов. Есть люди, для которых важно сделать, образно выражаясь, А, B, C и получить результат, им будут неинтересны ваши посты на вроде "Шла третья неделя упарывания шаблонами". А есть люди, для которых важно, не столько что делает программа, а то, чтобы было "красиво". Надеюсь теперь понятно. Я не в коем разе не считаю одних лучше других, и в первой, и во второй категории есть адекватные люди. Но я сомневаюсь, что Линус Торвальдс зачитывается Диекстрой.

eao197 комментирует...

@Stanislav Mischenko

> А есть люди, для которых важно, не столько что делает программа, а то, чтобы было "красиво".

Мне непонятно это "красиво". И я не стремлюсь сделать красиво, я пытаюсь сделать так, чтобы решение конкретной задачи было более компактно, надежно и проще в сопровождении, чем простое и тривиальное решение "в лоб".

Dmitry Popov комментирует...

Это здесь пример Higher-Kinded Type. За отсутствие которых любители хаскеля и других продвинутых ЯП ругали Раст.

Про переход С++ из класса рабочих и крестьян в класс заумной экзотики мысль интересная. История покажет...

eao197 комментирует...

@Dmitry Popov:

> История покажет...

Если послушать, чего люди пишут в Интернетах, так C++ продолжают использовать либо там, где он уже есть и это традиция (скажем, в легаси или в тяжелых играх, или в профессиональном софте для десктопа), либо там, где команда не боится использовать modern C++ по полной программе и этой команде не приходится думать о том, что написанный ими код придется отдавать на сопровождение индусам, только-только окончившим 3-х месячные курсы "войти-в-ИТ".