На LOR-е в обсуждении одной темы всплыла ссылка на фреймворк для Scala под названием LMS (Lightweight Modular Staging). На стартовой страничке есть коротенький примерчик:
class Vector[T:Numeric:Manifest](val data: Rep[Array[T]]) { def foreach(f: Rep[T] => Rep[Unit]): Rep[Unit] = for (i <- 0 until data.length) f(data(i)) def sumIf(f: Rep[T] => Rep[Boolean]) = { var n = zero[T]; foreach(x => if (f(x)) n += x); n } } |
Фреймворк LMS позволяет привести показанный выше код к более простому виду. Но суть не в этом.
Глядя на обобщенный Scala-вский код я подумал, что у C++ давно сложилась репутация не очень выразительного языка. Мол для выражения простых вещей требуется слишком много телодвижений.
Тем удивительнее было осознать, что в современном C++ именно этот пример может быть записан вполне себе лаконично и без сложной шаблонной магии. Собственно говоря полный вариант, который можно взять, скомпилировать и проверить, выглядит вот так (проверялось под GCC 5.3.0 в режиме C++14):
#include <iostream> #include <iterator> #include <vector> using namespace std; template< typename C, typename F > auto sum_if( C const & v, F f ) { std::decay_t< decltype(*begin(v)) > r{}; for( auto const & x : v ) if( f(x) ) r += x; return r; } int main() { vector< double > a = { 1.0, 2.0, 0.0, -2.0, -3.0, 4.0, 1.0 }; cout << sum_if( a, []( auto x ) { return x > 0; } ) << endl; } |
Код шаблонной функции sum_if ничуть не сложнее Scala-овского варианта. Даже при том, что C++ный может принимать на вход не только vector<T>, но и list, forward_list, deque и даже T[N].
Походу, с каждым годом стенания о недостаточной выразительности C++ все больше и больше переходят в категорию мифов. Что не может не радовать.
Комментариев нет:
Отправить комментарий