Wednesday, May 13, 2009

C++ 0x уже сегодня?

Вступление

С++ 0x - кодовое имя грядущего стандарта С++, который несет в себе огромное количество изменений. Если и до этого язык С++ был одним из самых нагруженных и сложных, то с приходом нового стандарта он может вообще быть погребен под собственной массой. Но случится ли это? Ответу на этот вопрос и посвящен данный пост.

Основная часть

На BoostCon было точно подмечено, что "С++ 0x" нужно читать как "C++ 0A","C++0B", etc, однако многое можно попробовать уже сейчас.
Для этого я собрал gcc из cxx0x-lambdas-branch, который, по-моему, сейчас максимально близок к C++0x (бранч периодически мержится с основной веткой, но в этом бранче полностью отстутствуют Concepts). О том, как собирать - смотрите ссылки ниже.
Итак, имеем:
$ bin/gcc --version
gcc (GCC) 4.5.0 20090421 (experimental)
Copyright (C) 2009 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Попробуем что-нибудь написать:
#include <iostream>
#include <vector>
#include <algorithm>


int main()
{
std::vector<int> v = {1,2,3,4,5};
std::vector<std::pair<int,int>> v2;
std::transform(v.begin(),
v.end(),
std::back_inserter(v2),
[](int x){return std::pair<int,int>(x, x*x);});
for_each(v2.begin(),v2.end(),[](std::pair<int,int> x){std::cout<<"("<<x.first<<","<<x.second<<")";});
int s = 0;
for_each(v.begin(),v.end(),[&s](int x){s+=x;});
std::cout<<"\nResult:"<<s<<"\n";
// static_assert(false, "Dummy assertion!");
auto is_42 = [](int x) {return x == 42;};
auto answer = 42;
if (is_42(answer))
{
std::cout<<"Yes, it is!\n";
}
decltype(answer + 42) new_answer = 43;//?
std::cout<<"New Answer:"<<new_answer<<"\n";
}
Впечатляет? Присмотритесь внимательней, в этом примере: initializer lists(список инициализации для v), right angle brackets (две правые угловые скобки в определении v2), lambda(с захватом переменных и без), static_assert (закомментирован), auto (для простых случаев и для лямбда-выражений), decltype(для определения типов). Меня очень впечатлило. Несмотря на то, что в язык добавлены новые элементы, язык стал только выразительней, а никак не сложнее.
Таким образом, С++ вбирает в себя всё новые и новые идеи. Несложно заметить, что С++ 0x - огромный шаг поближе к Haskell. Кто считает, что это чепуха - присмотритесь к Variadic Templates:
template<unsigned... Args> struct mysum;
template<>
struct mysum<> {
static const int value = 0;
};

template<unsigned x, unsigned... Args>
struct mysum<x, Args...> {
static const int value = x + mysum<Args...>::value;
};

int main()
{
static_assert(mysum<10,20,11,1>::value==42, "Wow!");
}
Variadic Templates уже доступны, однако работают не полностью.

Выводы

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

Ссылки

Спасибо за внимание!

9 comments:

  1. На жаль він не став від цього стрибка більш читабельним :(

    ReplyDelete
  2. Как я уже цитировал у себя в блоге:

    C++ is the steampunk of programming languages: modern ideas realized with victorian technology.

    ReplyDelete
  3. @akhavr
    Читабельність - це взагалі суб'єктивна штука. Ось багато хаскелістів вважають, що їх код читати дуже легко.

    @curvedbrain
    Согласен, С++ бывает многословен ;)

    ReplyDelete
  4. @Sergey Kishchenko
    Угу, суб'єктивна. Угу, легко. 100% легше ніж цей С++

    PS Коментарі на пошту не приходять?

    ReplyDelete
  5. @akhavr
    Теж саме, ІМХО. Якщо розумієш мову, то й Хаскель, й С++ тобі буде читати легко. Особливо якщо писати у правильному стилі. Бо у неправильному можна на будь-якій мові нечитабельну муру написати

    Мені приходять :), а ось опенідшникам - навіть і не знаю.

    ReplyDelete
  6. Я бы ещё добавил усовершенствованииий для ООП. Весьма актуально. С++ давно нуждается в доработке! Ещё бы perl доработать! Кстати там есть синтаксические конструкции недоступные на С++. Но есть и много проблем так же... Вобщем его ведёт Лари, скорей бы уже дуба дал, мы бы и perl привели к каноническому виду как надо! А то достал уже этот Лари своими комплексами доисторическими!

    ReplyDelete
  7. В С++ большая проблема... Легко написать код с очень трудноуловимыми ошибками. А так синтаксис весьма простой. В том-то и прелесть, что всё стабильно. Это вам не какой-нить фреймворк, который раз в 2 года переделывают по новой. Ну и все программы надо переписывать. Весело конечно, если не сказать печально! Друго дело С++ никаких фреймворков! Программа написаная давным давно работает и сейчас, ну или в крайнем случае перекомпилить надо! Все эти фишки давно есть в других языках... Но я бы не торопился с внедрением. Вначале надо отработать синтаксис, чтоб не было ошибок. А то получится промежуточная версия... Понапишут программ, а потом переделывать снова... Не хотелось бы однако. Но по закону Мерфи как ни старайся всё равно получатся косяки и будет не одна версия, тем более такие большие изменения... Лучше внедрять по частям всё же... Меньше проблем будет!

    ReplyDelete
  8. //Тоже самое на D 2.0 часть 1
    import std.cstream;
    import std.algorithm;
    import std.range;
    import std.conv;

    void main()
    {
    int[] v = [1,2,3,4,5];
    int[2][] v2 = array(map!"cast(int[2])[a, a*a]"(v));
    foreach(e; v2)
    dout.writef("(%s,%s)", e[0], e[1]);
    auto s = reduce!"a+b"(v);
    dout.writefln("\nResult:", s);
    //static assert(false, "Dummy assertion!"); , ещё есть static if =)))
    auto is_42 = (int x) { return x == 42; };
    auto answer = 42;
    if (is_42(answer))
    {
    dout.writefln("Yes, it is!");
    }
    typeof(answer+42) new_answer = 43;
    dout.writefln("New Answer:", new_answer);
    }

    ReplyDelete
  9. //Тоже самое на D 2.0 часть 2 вариант 1
    import std.algorithm;

    uint mysum(uint[] a...) {
    return reduce!"a+b"(a);
    }

    void main()
    {
    static assert(mysum(10,20,11,1) == 42, "WTF1");
    }

    ReplyDelete