27 марта 2009

RangeEx

Концепция итераторов в STL - замечательная вещь. Можно сказать это C++-ная замена С-шным указателям, причем обратно совместимая с последними. Но вот в реальной жизни пользоваться только итераторами не настолько удобно - чаще больше подходят более высокоуровневые концепции - диапазоны (ranges) и контейнеры. Чаще бывает удобнее писать copy(from, to), чем copy(from.begin(), from.end(), make_back_inserter(to)). Да и вернуть диапазон вместо пары итераторов гораздо удобнее:
encode(substring());
вместо
pair<iterator, iterator> sub(substring());
encode(sub.first, sub.second);
Помню как-то читал как Александреску в языке D активно продвигает диапазоны вообще на замену итераторам. Можно так критично не относиться к итераторам, но я при написании кода вовсю стараюсь специализировать алгоритмы не только для итераторов, но и диапазонов. Алгоритмы в Boost, кстати, тоже очень range-friendly.

И очень правильный шаг в этом направлении - [Boost.]RangeEx. Эта библиотека позволяет сильно упростить код, который до этого использовал итераторы. Конечно, раньше кое-как спасал Boost.Iterators, но код был не в пример этому:
boost::copy(rng |
boost::adaptors::filtered(pred) |
boost::adaptors::unique,
out)
Синтакис очень знаком:
ls | grep ".xml" | wc -l

Вобщем, я очень проникся и вам советую попробовать.

12 марта 2009

Прибирайте за собой

Довольно просто на стороне клиента открыть полученный с сервера файл в его родном приложении: ShellExecute(..., FileName, ...)

Единственное, перед этим нужно сохранить файл на диск. Например, во временную папку. Вопрос только - когда его удалять? Сразу же после вызова ShellExecute() это делать вряд ли разумно - запущенное приложение может не успеть еще забрать данные из файла. А может успеть открыть файл, и оставить его заблокированным на время просмотра.

Ничего красивее чем MoveFileEx(FileName, NULL, MOVEFILE_DELAY_UNTIL_REBOOT) в голову не приходит. Правда до ближайшего ребута может быть много лет, но на клиентских машинах такое редко бывает. С другой стороны - многие вообще не прибирают за собой временные файлы, так что это лучше чем ничего.

Интересно, есть ли более элегантное решение?