Здравствуйте, AVC, Вы писали:
AVC>Здравствуйте, IT, Вы писали:
IT>>Со всех сторон бедные плюсы подпёрли. Сишники-пуританцы снизу, дотнетчики сверху
AVC>Сверху, снизу... AVC>Дождемся, кто пристроится сзади...
Здравствуйте, WolfHound, Вы писали:
WH>А если так WH>
WH>void Foo(int min, int max)
WH>{
WH> auto predicat = bool lambda( int x ) { return min < x && x <= max };
WH> int count = count_if( ints.begin(), ints.end(), predicat );
WH> ...
WH> auto int_it = find_if( ints.begin(), ints.end(), predicat );
WH> ...
WH>}
WH>
WH>Ы? WH>Вся суть этого примера в том что функция имеет доступ к контексту. WH>Без таких вещей STL так и останится жутиком которым пользоваться невозможно.
using namespace boost::lambda;
count_if(ints.begin(), ints.end(), min < _1 && _1 <= max);
Мое предсказание насчёт C++0x: лямбды не будет. Потому что написать предложение в стандарт, в котором простейшие выражения будут короче чем boost::lambda, ни у кого не выйдет. (а то предложение, которое сейчас есть — фигня полная, там даже лямбда выражений нет)
Cyberax коротенький тестик привел для замера скорости работы FS, так к этому тесту нужно буст тащить, да еще версию из CVS.
А в чём проблема? CVS трудно поставить? А в большинстве Линуксов Boost вообше по умолчанию ставится.
> Уж на самом деле, на C в таких условиях писать спокойнее.
CVS поставить и сделать checkout boost'у быстрее. Даже если собрать прийдётся, всё равно быстрее. А пока оно собирается, можно чем-нибудь полезным заняться...
Здравствуйте, Left2, Вы писали:
E>>Ошибся. Было ключевое слово overload, от него отказались, но в первом издании своей книги Страуструп его использовал.
L>Во как! L>Что-то я не помню такого в "как я рожал ёжиков"... А почему отказались — он не говорил?
11.2.4. The overload Keyword
Originally, C++ allowed a name to be used for more than one name (that is, "to be overloaded") only after an explicit overload declaration. For example:
overload max; // ``overload'' — obsolete in 2.0
int max(int,int);
double max(double,double);
I considered it too dangerous to use the same name for two functions without explicitly declaring an intent to overload. For example:
int abs(int); // no ``overload abs''
double abs(double); // used to be an error
This fear of overloading had two sources:
[1] Concern that undetected ambiguities could occur.
[2] Concern that a program could not be properly linked unless the programmer explicitly declared which functions were supposed to be overloaded.
The former fear proved largely groundless. The few problems found in actual use are dealt with by the order-independent overloading resolution rules. The later fear proved to have a basis in a general problem with C separate compilation rules that had nothing to do with overloading.
On the other hand, the overload declarations themselves became a serious problem. One couldn't merge pieces of software using the same function name for different functions unless both pieces had declared that name overloaded. This wasn't usually the case. Typically, the name one wants to overload is the name of a C library function declared in a C header. For example:
/* Header for C standard math library, math.h: */
double sqrt(double);
/* ... */
// header for C++ complex arithmethic library, complex.h:
overload sqrt;
complex sqrt(complex);
Now we could write
#include <complex.h>
#include <math.h>
but not
#include <math.h>
#include <complex.h>
because it was an error to use overload for sqrt() on its second declaration only. There were ways of alleviating this: rearranging declarations, putting constraints on the use of header files, and sprinkling overload declarations everywhere "just in case." However, we found such tricks unmanageable in all but the simplest cases. Abolishing overload declarations and getting rid of the overload keyword worked much better.
Здравствуйте, eao197, Вы писали:
E>Экспериментальным путем удалось установить, что overload писать не нужно (в примерах к Turbo C++ нашел работающую перегрузку функций без overload). И только через несколько лет узнал всю правду про overload :)
Дак в то время какие-то добрые люди перевели документацию к Turbo C++ и выложили в виде текстовых файлов. У меня она до сих пор дома где-то в архивах лежит. Там и про overload было.
И, если не ошибаюсь, protected-доступ к данным тоже появился в Turbo C++, и там его увидел Страуструп.
E>Забавно, что печатное издание этой книги я смог купить где-то в 1993-м, то там overload еще использовался :)
Я тоже. К нему еще какое-то дополнение шло в виде брошюры. К сожалению, не сохранилось.
E>В C++ для одного стандартного GUI поезд уже ушел, имхо.
Мне наоборот кажется, что только вот сейчас появляется возможность сделать более-менее стандартную GUI-библиотеку. Ведь GUI оно существует не само по себе, для ее реализации требуются такие абстракции:
— файловая система
— ресурсы, графика
— блокировки OC и прочая многозадачность
— таймеры
— событийная модель
Ничего этого и близко не было в некоем "стандартном" виде до недавнего времени, и только вот сейчас boost набирает достаточно "мяса", чтобы замахнуться на "стандартный" GUI.
Здравствуйте, vdimas, Вы писали:
V>Ничего этого и близко не было в некоем "стандартном" виде до недавнего времени, и только вот сейчас boost набирает достаточно "мяса", чтобы замахнуться на "стандартный" GUI.
И что, boost будет создавать свой GUI с нуля?
Так же, как они делали с многопоточностью, с асинхронным вводом/выводом и пр. околосистемными вещами? Переписывая заново то, что уже было в других библиотеках, в частности в ACE.
И, например, у меня сейчас есть выбор -- либо использовать ACE (который "C с классами" и во многих случаях предоставляет только C-шные функции), зато работает практически везде, либо брать Boost. И при том, что ACE даже меньше по объему, чем тот же Boost. Не очень радостный выбор, надо сказать. Т.к. Boost набирает популярность и явно становиться мейнстримом в C++.
И что делать с наработками, использующими уже существующие библиотеки (FOX, FLTK, Qt, Ultima++)? Тянуть старые проекты на них, а новые делать на стандартном C++ GUI?
eao197 wrote: > И что, boost будет создавать свой GUI с нуля? > Так же, как они делали с многопоточностью, с асинхронным вводом/выводом > и пр. околосистемными вещами? Переписывая заново то, что уже было в > других библиотеках, в частности в ACE.
Хотя получилось совсем неплохо — тот же asio использовать намного
приятнее, чем ACE (и еще в asio есть фичи типа возможности
неиспользования динамической памяти).
> И, например, у меня сейчас есть выбор -- либо использовать ACE (который > "C с классами" и во многих случаях предоставляет только C-шные функции), > зато работает практически везде, либо брать Boost. И при том, что ACE > даже меньше по объему, чем тот же Boost.
Тот же asio — совсем немного занимает и размещается полностью в хидерах.
Хотя в ACE просто есть много того, что пока нет в Boost'е (например,
реализация CORBA в TAO).
> Маловероятно это все.
A> using namespace boost::lambda;
A> count_if(ints.begin(), ints.end(), min < _1 && _1 <= max);
A>
A>Мое предсказание насчёт C++0x: лямбды не будет. Потому что написать предложение в стандарт, в котором простейшие выражения будут короче чем boost::lambda, ни у кого не выйдет. (а то предложение, которое сейчас есть — фигня полная, там даже лямбда выражений нет)
Не имешите мои тапочки. Я про boost::lambda прекрасно знаю. Фуфло это. Позволяет описывать только простейшие выражения. А как нужно что-то по сложнее то все. Приехали... столько кода писать приходится что проще в место алгоритма for написать.
struct Point
{
int x;
int y;
};
struct Rect
{
Point p1;
Point p2;
};
...
count_if(rects.begin(), rects.end(), bool(auto& rect){return min < rect.p1.x && rect.p2.y <= max});
Нука изобрази на boost::lambda... А если понадобится болие сложная логико то... А сколько времени оно компилится...
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, eao197, Вы писали:
E>- проведенный-таки deadline по предложениям к новому стандарту языка.
Анекдот в тему:
Милицейская хроника: 10 декабря возле летнего кинотеатра были найдены двое отмороженных. По словам потерпевших, они ожидали начало сеанса фильма "Закрыт на зиму".
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, alexeiz, Вы писали:
A>>А в чём проблема? CVS трудно поставить?
AVK>CVS через прокси и фаерволы без специальной настройки не ходит.
sourceforge имеет сервер с cvs на портах 80 и 443 (http/https), которые открыты на firewall'ах
Здравствуйте, alexeiz, Вы писали:
A>sourceforge имеет сервер с cvs на портах 80 и 443 (http/https), которые открыты на firewall'ах
Эээ, как бы тебе объяснить. Вобщем частенько ситуация такая — есть только http-прокси и настроить ее нельзя. Так вот — через нее к CVS не сходишь. А фаерволы да, таким манером обойти можно.
... << RSDN@Home 1.2.0 alpha rev. 646 on Windows XP 5.1.2600.131072>>
Здравствуйте, WolfHound, Вы писали:
WH>В подавляющем большинстве случаев повторная применимость таких классов нафиг не уперлась. Вот скажи мне часто тебе нужна возможность повторного использования ветки оператора if? Или тела цикла for?
Темболее, что если надо, то это в любом языке делается.
Вот только с замыканиями и локальными фунциями это можно делать удобнее и чаще:
SomeMethod(x : int) : bool
{
def Greater(y) { x > y }
def Equals(y) { x == y }
def GreaterOrEquals(y) { Greater(y) || Equals(y) }
if (GreaterOrEquals(10))
...
else if (GreaterOrEquals(2))
...
else if (Equals(1))
...
...
}
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, vdimas, Вы писали:
WH>>В подавляющем большинстве случаев повторная применимость таких классов нафиг не уперлась. Вот скажи мне часто тебе нужна возможность повторного использования ветки оператора if? Или тела цикла for?
V>Функциональщики считают, что да. посмотри на программы на Схеме, например. Там программы — это макраме из массы очень коротких, по сравнению с "обычными", процедур.
У функциональщиков как раз есть замыкания и "массы очень коротких" функций они объявляют по месту используя контекст методов в которые они вложены.
Так что твой аргумент скорее против С++, чем за.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
A> using namespace boost::lambda;
A> count_if(ints.begin(), ints.end(), min < _1 && _1 <= max);
A>
A>Мое предсказание насчёт C++0x: лямбды не будет.
Почти уверен, что ты ошибашся, но если ты все же окажешся прав, то это кончиной языка.
A> Потому что написать предложение в стандарт, в котором простейшие выражения будут короче чем boost::lambda, ни у кого не выйдет.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, alexeiz, Вы писали:
A>>
A>> using namespace boost::lambda;
A>> count_if(ints.begin(), ints.end(), min < _1 && _1 <= max);
A>>
A>>Мое предсказание насчёт C++0x: лямбды не будет. Потому что написать предложение в стандарт, в котором простейшие выражения будут короче чем boost::lambda, ни у кого не выйдет. (а то предложение, которое сейчас есть — фигня полная, там даже лямбда выражений нет) WH>Не имешите мои тапочки. Я про boost::lambda прекрасно знаю. Фуфло это.
Твой синтакс тоже фуфло. Ну что такое bool(auto& rect){return ..., что это!? Вот так должно быть:
count_if(begin(), end(), fun x => min < x.p1.x && x.p2.y <= max);
>Позволяет описывать только простейшие выражения. А как нужно что-то по сложнее то все. Приехали... столько кода писать приходится что проще в место алгоритма for написать. WH>
WH>struct Point
WH>{
WH> int x;
WH> int y;
WH>};
WH>struct Rect
WH>{
WH> Point p1;
WH> Point p2;
WH>};
WH>...
WH>count_if(rects.begin(), rects.end(), bool(auto& rect){return min < rect.p1.x && rect.p2.y <= max});
WH>
WH>Нука изобрази на boost::lambda...
return count_if(ints.begin(), ints.end(), min < &(&_1 ->* &Rect::p1) ->* &Point::x && max <= &(&_1 ->* &Rect::p2) ->* &Point::y);
>А если понадобится болие сложная логико то...
Я лучше функтор напишу. Но в простейших вещах трудно по краткости с boost::lambda тягаться.
>А сколько времени оно компилится...
Здравствуйте, alexeiz, Вы писали:
A>Твой синтакс тоже фуфло. Ну что такое bool(auto& rect){return ..., что это!? Вот так должно быть: A>
count_if(begin(), end(), fun x => min < x.p1.x && x.p2.y <= max);
А это уже не суть важно. Синтаксический оверхед O(1) . В C#3 можно и так и так. Короткий синтаксис для простых случаев, длинный если нужно что-то навороченое с циклами, временными переменными и тп...
A>
A> return count_if(ints.begin(), ints.end(), min < &(&_1 ->* &Rect::p1) ->* &Point::x && max <= &(&_1 ->* &Rect::p2) ->* &Point::y);
A>
О! На таком примитиве гора непонятного кода... И что после этого boost::lambda рулит? А если это все еще и шаблонами посыпать..., а если нужен вложеный цикл... Короче тушите всет.
A>Я лучше функтор напишу.
А я for. Ибо с очень большой вероятностью этот функтор понадобится ровно один раз. A>Но в простейших вещах трудно по краткости с boost::lambda тягаться.
Ну разве что в совсем простейших. Я бы даже сказал примитивных. Вот только примитивных случаев очень не много. Как правило что-то по сложнее типа того кода что выше.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, VladD2, Вы писали:
V>>Функциональщики считают, что да. посмотри на программы на Схеме, например. Там программы — это макраме из массы очень коротких, по сравнению с "обычными", процедур.
VD>У функциональщиков как раз есть замыкания и "массы очень коротких" функций они объявляют по месту используя контекст методов в которые они вложены.
Чего гадать? Возьми любые исходники на Схеме чего-нить (полно в сети) да посмотри. Локальные замыкания в Паскалевском стиле не так уж часто используются. А по мне, есть в этом что-то от использования глобальных переменных. Кстати, в Паскале, глобальные переменные — это окружение замыкания процедуры program. (на слух звучит коряво, но "envirounment/окружение" — это термин такой для замыканий)
VD>Так что твой аргумент скорее против С++, чем за.
Да он и не за и не против. Я просто показал как можно на С++ эмулировать замыкания с помощью функциональных объектов. Разумеется, лучше пусть за нас эту работу делает компилятор... А повторную применимость функциональных объектов в С++ можно рассматривать как побочный полезный эффект, т.е. есть шанс, что лишные пару строк на описание функционального объекта могут "отбиться".