Эквивалентная реализация на C++ будет раза в 2 длиннее из-за необходимости прописывать библиотечные типы std::function, std::map, std::string там, где D использует встроенные типы. Гораздо важнее то, что нужно больше внимания уделять логике передачи параметров и возврата результата по значению или ссылке: на С++ я бы предпочёл возвращать функцию с типом «void (map&)».
Чтобы в C++11 компилятор делал черновую работу, и сам решал что и как собирать в функцию можно использовать синтаксис [=], [&]. Первый вариант будет сохранять копию используемых переменных в функциональном объекте, второй — сохраняет ссылки. Лично я [=], [&] предпочитаю не пользоваться, и явно специфицирую, что и как должно сохраняться («Explicit is better than implicit», Zen of Python)
А вообще было бы интересно почитать об особенностях, для которых нет аналогов в языке или библиотеке C++11; о новых стилях программирования используя D.
Мне кажется, что выход стандарта C++11 был сильным шагом. Приведённый ниже код уже поддерживается распространёнными компиляторами (проверено Visual Studio 2010, должен работать с gcc, где поддержка нового стандарта более полная). Код похож на примеры приведённые в статье. Думаю, что если стоит выбор куда инвестировать свои усилия, в изучение C++11, или в изучение D, у C++11 есть определённые преимущества. Мы уже сейчас активно используем реализованное в Visual Studio 2010 подмножество C++11 в production, и впечатления очень хорошие.
int incTwice(int a)
{
auto inc = []( int i ) { return i+1; };
return inc(inc(a));
}
#include <functional>
void testLambdas(int c)
{
auto f = []( int a ) { return a+1; };
std::function<int(int)> f2 = []( int a ) { return a+1; };
auto inc = [c] (int a) { return a+c; };
}
Мне кажется, что этот вариант хуже, и чем вариант со структурой, и чем вариант с парой.
— Читабельность не улучшится: будут использоваться first/second, не давая информации о том что реально хранится в этом поле
— Вероятность совершить ошибку не изменится. Оба типа Name, String представляют из себя синонимы типа string. Можно легко присвоить имени фамилию, и наоборот
— Засоряется пространство имён типами, не несущими большой смысловой нагрузки
— Код не стал более коротким по сравнению с использованием структуры
Хотелось бы, конечно, чтобы все фичи поддерживались, но для десятки это было недостижимо. При всём этом они реализовали достаточно сбалансированный набор, покрыв критически важные вещи.
Лично мне жалко, что не было возможности включить «Initializer lists», «Defaulted and deleted functions» и «Range-based for». Variadic templates, мне кажется, больше нацелены на авторов библиотек общего назначения, к которым я себя не отношу.
Мне кажется, что полезность goto в мире C++ значительно ниже, чем в мире C.
1. Дело даже не в пресловутых исключениях. Например, я не считаю, что использование исключений для выхода из вложенного цикла оправданно. Думаю, что killer-feature, делающая goto малополезной это автоматический вызов деструкторов созданных объектов.
Рассмотрим один из примеров использования goto в языке C.
void f()
{
// выделение ресурсов
// goto ... goto ... goto ...
EXIT:
// освобождение ресурсов
}
2. Полагаю, что несмотря ни на что goto в программах на C++ может встречаться, например, в автоматически сгенерированном коде. Однако ваши примеры с «флажками» и без выглядят переусложнёнными, и немного надуманными. Мне кажется, что подобный код в промышленном коде нежелателен, так как не читается «влёт». Если есть возможность, его стоило бы переписать, и потом уже оценивать мощь goto.
3. Широко распространено мнение, что выход из вложенного цикла является хорошим кандидатом на использование goto. Возможно и так. Однако в моей практике выделение новых функций улучшало читабельность, и облегчало дальнейшее сопровождение программы.
Думаю, что с появлением C++0x ваш можно будет реализовать более элегантно. Я бы советовал посмотреть в сторону variadic templates и user-defined literals. Вот пример из статьи C++0x в википедии:
Вы не предлагаете пользователю обновить версию используемого браузера: в списке нет обновлений для продукта, с которым вы боретесь. Вместо этого предлагается использовать совершенно новый продукт. При всей своей любви к альтернативным браузерам (сам ими с удовольствием пользуюсь), мне кажется, что не стоит так неуважительно относиться к своим пользователям.
Уверяю, что это внешнее сходство, мне не очень понятное. Может дело в том, что я немного знаком с OCaml, Haskell :). Кроме пары ключевых слов найти что-то общее между F# и Basic сложно. Кстати let, with активно используются и в других языках.
Чтобы в C++11 компилятор делал черновую работу, и сам решал что и как собирать в функцию можно использовать синтаксис [=], [&]. Первый вариант будет сохранять копию используемых переменных в функциональном объекте, второй — сохраняет ссылки. Лично я [=], [&] предпочитаю не пользоваться, и явно специфицирую, что и как должно сохраняться («Explicit is better than implicit», Zen of Python)
А вообще было бы интересно почитать об особенностях, для которых нет аналогов в языке или библиотеке C++11; о новых стилях программирования используя D.
— Читабельность не улучшится: будут использоваться first/second, не давая информации о том что реально хранится в этом поле
— Вероятность совершить ошибку не изменится. Оба типа Name, String представляют из себя синонимы типа string. Можно легко присвоить имени фамилию, и наоборот
— Засоряется пространство имён типами, не несущими большой смысловой нагрузки
— Код не стал более коротким по сравнению с использованием структуры
Лично мне жалко, что не было возможности включить «Initializer lists», «Defaulted and deleted functions» и «Range-based for». Variadic templates, мне кажется, больше нацелены на авторов библиотек общего назначения, к которым я себя не отношу.
1. Дело даже не в пресловутых исключениях. Например, я не считаю, что использование исключений для выхода из вложенного цикла оправданно. Думаю, что killer-feature, делающая goto малополезной это автоматический вызов деструкторов созданных объектов.
Рассмотрим один из примеров использования goto в языке C.
Подобный код в C++ используется реже, благодаря идиоме RAII (Resource Acquisition Is Initialization). Этот код в C++ скорее всего будет выглядеть так:
2. Полагаю, что несмотря ни на что goto в программах на C++ может встречаться, например, в автоматически сгенерированном коде. Однако ваши примеры с «флажками» и без выглядят переусложнёнными, и немного надуманными. Мне кажется, что подобный код в промышленном коде нежелателен, так как не читается «влёт». Если есть возможность, его стоило бы переписать, и потом уже оценивать мощь goto.
3. Широко распространено мнение, что выход из вложенного цикла является хорошим кандидатом на использование goto. Возможно и так. Однако в моей практике выделение новых функций улучшало читабельность, и облегчало дальнейшее сопровождение программы.