Информация об изменениях

Сообщение Re: Критика современного С++ от 05.02.2019 19:38

Изменено 05.02.2019 19:42 Voivoid

Re: Критика современного С++
Здравствуйте, Nuzhny, Вы писали:

N>От разработчиков Unity.

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

Авторы статьи ничего не поняли, но поспешили пойти поплакаться. Правда справедливости ради стоит сказать, что и сам Eric Niebler привел весьма неудачный пример .

ranges v3 просто бомбическая библиотека значительно облегчающая:
— отделение алгоритмов от структур данных
— использование функциональной композиции
— создание ленивых алгоритмов
— написание генераторов

Небольшой компилируемый пример для затравки:

#include <range/v3/view/transform.hpp>
#include <range/v3/view/filter.hpp>
#include <range/v3/view/take.hpp>
#include <range/v3/view/map.hpp>
#include <range/v3/view/cycle.hpp>
#include <range/v3/view/reverse.hpp>
#include <range/v3/algorithm/copy.hpp>
#include <range/v3/iterator/stream_iterators.hpp>

#include <iostream>
#include <vector>
#include <set>
#include <map>

using namespace ranges;

auto some_algo()
{
    // некоторый алгоритм который ничего не знает о структурах данных и работает с произвольной последовательностью
    return view::transform( []( auto x ){ return x * 2; } ) |                // умножаем числа последовательности на 2
           view::filter( []( auto x ){ return x >= 10 && x <= 100; } ) |     // фильтруем числа не входящие в диапазон [10, 100]
           view::take( 4 );                                                  // берем не более 4 чисел из оставшихся после фильтрации
}

template <typename R>
void print( R&& range ) 
{
    // печать на консоль произвольной последовательности
    copy( range, make_ostream_joiner( std::cout, "," ) );
    std::cout << '\n';
}

int main()
{
    std::vector<int> vs = { 5, 10, 15, 20, 25 };
    print( vs );                // печатаем содержимое vs
    print( vs | some_algo() );  // печатаем последовательность полученную после применения алгоритма some_algo к vs

    std::set<double> ss = { 15.5, 30.0, 42.4242, 100.0 };
    print( ss | some_algo() );  // аналогично для ss

    std::map<int, int> m = { { 10, 20 }, { 30, 40 }, { 50, 60 } };
    auto some_range = m | view::keys | some_algo() | view::cycle | view::take( 10 ); // берем последовательность ключей мапы ( 10, 30, 50 )
                                                                                     // применяем наш алгоритм
                                                                                     // зацикливаем получившуюся последовательно
                                                                                     // берем из зацикленной ( бесконечной ) последовательности первые 10 элементов
    print( some_range );

    for( auto v : m | view::values | view::reverse )  // обходим в цикле значения мапы в обратном порядке
    {
        std::cout << v << ' ';
    }

}

/*
output:
5,10,15,20,25
10,20,30,40
31,60,84.8484
20,60,100,20,60,100,20,60,100,20
60 40 20
*/


Одних только всяких разных view'ек в range v3 более 50-ти. А кроме них еще достаточно всего полезного. Вкупе с использованием boost::coroutines писать алгоритмы на C++ становится практически так же приятно, как и на функциональных языках ( хоть и увы, код конечно не такой лаконичный получается )
Re: Критика современного С++
Здравствуйте, Nuzhny, Вы писали:

N>От разработчиков Unity.

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

Авторы статьи ничего не поняли, но поспешили пойти поплакаться. Правда справедливости ради стоит сказать, что и сам Eric Niebler привел весьма неудачный пример .

ranges v3 просто бомбическая библиотека значительно облегчающая:
— отделение алгоритмов от структур данных
— использование функциональной композиции
— создание ленивых алгоритмов
— написание генераторов

Небольшой компилируемый пример для затравки:

#include <range/v3/view/transform.hpp>
#include <range/v3/view/filter.hpp>
#include <range/v3/view/take.hpp>
#include <range/v3/view/map.hpp>
#include <range/v3/view/cycle.hpp>
#include <range/v3/view/reverse.hpp>
#include <range/v3/algorithm/copy.hpp>
#include <range/v3/iterator/stream_iterators.hpp>

#include <iostream>
#include <vector>
#include <set>
#include <map>

using namespace ranges;

auto some_algo()
{
    // некоторый алгоритм который ничего не знает о структурах данных и работает с произвольной последовательностью
    return view::transform( []( auto x ){ return x * 2; } ) |                // умножаем числа последовательности на 2
           view::filter( []( auto x ){ return x >= 10 && x <= 100; } ) |     // фильтруем числа не входящие в диапазон [10, 100]
           view::take( 4 );                                                  // берем не более 4 чисел из оставшихся после фильтрации
}

template <typename R>
void print( R&& range ) 
{
    // печать на консоль произвольной последовательности
    copy( range, make_ostream_joiner( std::cout, "," ) );
    std::cout << '\n';
}

int main()
{
    std::vector<int> vs = { 5, 10, 15, 20, 25 };
    print( vs );                // печатаем содержимое vs
    print( vs | some_algo() );  // печатаем последовательность полученную после применения алгоритма some_algo к vs

    std::set<double> ss = { 15.5, 30.0, 42.4242, 100.0 };
    print( ss | some_algo() );  // аналогично для ss

    std::map<int, int> m = { { 10, 20 }, { 30, 40 }, { 50, 60 } };
    auto some_range = m | view::keys        // берем последовательность ключей мапы ( 10, 30, 50 )
                        | some_algo()       // применяем наш алгоритм
                        | view::cycle       // зацикливаем получившуюся последовательно
                        | view::take( 10 ); // берем из зацикленной ( бесконечной ) последовательности первые 10 элементов

    print( some_range );

    for( auto v : m | view::values | view::reverse )  // обходим в цикле значения мапы в обратном порядке
    {
        std::cout << v << ' ';
    }

}

/*
output:
5,10,15,20,25
10,20,30,40
31,60,84.8484
20,60,100,20,60,100,20,60,100,20
60 40 20
*/


Одних только всяких разных view'ек в range v3 более 50-ти. А кроме них еще достаточно всего полезного. Вкупе с использованием boost::coroutines писать алгоритмы на C++ становится практически так же приятно, как и на функциональных языках ( хоть и увы, код конечно не такой лаконичный получается )