пятница, 16 октября 2015 г.

[prog.c++11] В стандарте C++ нет writeln, какая жалость...

Тут вот народ удивляется, что в C++ до сих пор нет writeln. Мол, C++ники вместо xs.writeln все еще кипятят используют std::copy(std::begin(xs), std::end(xs), std::ostream_iterator(std::cout)); std::cout << std::endl;

Действительно, что-то вроде свободной шаблонной функции writeln, которая берет поток и объект-последовательность, и отображает все элементы последовательности в поток, не помешала бы. Но в стандартной библиотеке C++ нет столько всего полезного, что сожалеть об отсутствии writeln в голову как-то и не приходит.

Может быть потому, что написать writeln можно буквально с полпинка:

templatetypename STREAM, typename SEQUENCE >
void
writeln( STREAM && to, SEQUENCE && what )
{
   using type = decltype(*std::begin(what));
   std::copy( std::begin(what), std::end(what), std::ostream_iterator<type>(to) );
   to << std::endl;
}

Под катом тестовая программка, на которой проверялась работоспособность.

#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>

templatetypename STREAM, typename SEQUENCE >
void
writeln( STREAM && to, SEQUENCE && what )
{
   using type = decltype(*std::begin(what));
   std::copy( std::begin(what), std::end(what), std::ostream_iterator<type>(to) );
   to << std::endl;
}

class buffer
{
   char m_data[ 10 ];
public :
   buffer()
   {
      char c = 'A';
      forauto & t : *this ) t = c++;
   }

   char * begin() { return m_data; }
   char * end() { return m_data + sizeof(m_data); }
};

int main()
{
   buffer b;

   int i[] = { 12345 };

   std::vector< std::string > s = { "abc""---""abc" };

   writeln( std::cout, b );
   writeln( std::cout, i );
   writeln( std::cout, s );
}

Комментариев нет: