int nArgs = 0;
LPWSTR *Args = CommandLineToArgvW(GetCommandLineW(), &nArgs);
bool Silent = false;
if ((nArgs == 2) ||
((nArgs == 3) && boost::equals(Args[2], L"/silent") && (Silent = true)))
DoSomething(Args[1], Silent);
29 Март 2011
Silent ;)
"Ленивые" логические операторы позволяют писать такой забавный код:
18 Ноябрь 2010
(std::max)
Как-то давно я советовал бороться с макросами min/max из windows.h таким образом:
#include <windows.h>Напомню в чем суть проблемы: после включения windows.h уже нельзя писать
#ifdef min
#undef min
#endif
#ifdef max
#undef max
#endif
std::max(a,b). Оказывается все гораздо проще: можно писать (std::max)(a,b). Препроцессор обойдет такую запись стороной. Тогда не нужны undef-ы (актуально если потом вдруг нужно включить что-нибудь типа atl*.h).
16 Сентябрь 2010
Local functions in C++
В Pascal есть замечательная вещь - локальные функции. Иногда они ну ооочень удобны. Если кто с Паскалем не знаком, на C++ это бы выглядело примерно так:
В C++ такого счастья нет. Может такого не сделали из-за того, что в Сях стек устроен немного по-другому, нежели в Паскале (в любом случае - не оправдание), может Бьярн счел это "не тру". Конечно, можно написать локальный класс, у которого будет нужная функция, но которому придется вручную передавать нужные переменные - но это неудобно, да и выглядит ужасно. Вот как-то так:утка локальная функция?!
int foo(int x)То есть тело такой функции пишется внутри другой функции, и она может ссылать на ее переменные.
{
int y = 0;
void bar(int z)
{
y += x*z;
}
bar(1);
bar(2);
return y;
}
В C++ такого счастья нет. Может такого не сделали из-за того, что в Сях стек устроен немного по-другому, нежели в Паскале (в любом случае - не оправдание), может Бьярн счел это "не тру". Конечно, можно написать локальный класс, у которого будет нужная функция, но которому придется вручную передавать нужные переменные - но это неудобно, да и выглядит ужасно. Вот как-то так:
int foo(int x)Но с новым стандартом этот способ стал гораздо короче в записи:
{
int y = 0;
class foobar
{
public:
bar(int &y, int x) : y(y), x(x)
{
}
void operator ()(int z)
{
y += x*z;
}
private:
int &y, x;
} bar(y, x);
bar(1);
bar(2);
return y;
}
int foo(int x)Если сравнить с кодом, приведенным в начале - отличия минимальны! А уж если оно выглядит как утка, плавает как утка и крякает как утка - то чем не
{
int y = 0;
auto bar = [&](int z)
{
y += x*z;
};
bar(1);
bar(2);
return y;
}
16 Июль 2010
Mini HTTP server
Понадобился в приложении мини http сервер и http клиент. С клиентом все просто - можно просто воспользоваться функциями WinInet, написав к ним немного C++-оберток.
Сервер можно довольно просто написать на Boost.Asio, но оказалось все уже изобретено - хорошо подошла cpp-netlib, вот пример кода сервера из документации:
Библиотека, правда, довольно сырая - пришлось немного допиливать напильником чтобы скомпилировалась под VC++10. Но зато в комплекте идут приятные бонусы типа url_decode, которые вполне пригодились.
PS. Забавно было когда сделал и запустил простейший сервер - FireFox грузил http://localhost/ очень долго, дольше чем http://www.yandex.ru/. Я уж было стал грешить на cpp-netlib и boost.asio, но оказалось IE открывал localhost мгновенно. Как я понял, FF долго ресолвит адрес localhost (причем каждый раз видимо заново), а http://127.0.0.1/ открывает мгновенно.
Сервер можно довольно просто написать на Boost.Asio, но оказалось все уже изобретено - хорошо подошла cpp-netlib, вот пример кода сервера из документации:
struct hello_world;
typedef http::serverserver;
struct hello_world {
void operator() (server::request const &request,
server::response &response) {
response = server::response::stock_reply(
server::response::ok, "Hello, World!");
}
void log(...) {
// do nothing
}
};
hello_world handler;
http::serverserver_("0.0.0.0", "80", handler);
server_.run();
Библиотека, правда, довольно сырая - пришлось немного допиливать напильником чтобы скомпилировалась под VC++10. Но зато в комплекте идут приятные бонусы типа url_decode, которые вполне пригодились.
PS. Забавно было когда сделал и запустил простейший сервер - FireFox грузил http://localhost/ очень долго, дольше чем http://www.yandex.ru/. Я уж было стал грешить на cpp-netlib и boost.asio, но оказалось IE открывал localhost мгновенно. Как я понял, FF долго ресолвит адрес localhost (причем каждый раз видимо заново), а http://127.0.0.1/ открывает мгновенно.
21 Июнь 2010
Lexical_cast using Spirit
Если хочется быстро заменить lexical_cast на парсеры из Spirit-а (для увеличения скорости парсинга, например):
template <class T>
inline T spirit_cast(std::string const & input)
{
T value;
std::string::const_iterator begin = input.begin();
bool result = boost::spirit::qi::parse(begin, input.end(), value);
if (!result || begin != input.end())
throw std::bad_cast();
return value;
};
11 Май 2010
News: good one and bad one
Новая Visual Studio 2010 огорчила: CRT поддерживает операционные системы не ниже WinXP SP2 и Win2003 SP1. Забудьте про Win2000 и даже WinXP без SP2. Это весьма печально.
А новый Boost 1.43 порадовал: наконец-то добавили RangeEx. Это очень радует. Да что уж там - это будет мой следующий любимый релиз после 1.39, где был добавлен ForEach. ;)
А новый Boost 1.43 порадовал: наконец-то добавили RangeEx. Это очень радует. Да что уж там - это будет мой следующий любимый релиз после 1.39, где был добавлен ForEach. ;)
01 Май 2010
Comma operator returns
RAII в C++ - замечательная вещь. Количество кода сокращается на порядок (ну, если мыслить в двоичной системе исчисления, то в 2 раза - это на порядок, в 4 раза - уже на два порядка).
Например, следующий код дает нам возможность показать курсорчик "думаем..." и убрать его когда мы додумаем:
Но вот такой случай заставляет нас вручную восстанавливать курсор:
Вот тут-то и приходит на помощь старый добрый оператор запятая. Трюк в чем: при вычислении выражения все его аргументы живут до конца вычисления всего выражения. Построим выражение, где у нас будет "думающий" курсор и наша операция:
Например, следующий код дает нам возможность показать курсорчик "думаем..." и убрать его когда мы додумаем:
{
WTL::CWaitCursor WaitCursor;
SomeOperation();
}Не нужно руками восстанавливать курсор ни в случае если операция завершится успешно, ни в случае если кинет исключение. Все сделает деструктор класса CWaitCursor.Но вот такой случай заставляет нас вручную восстанавливать курсор:
{
WTL::CWaitCursor WaitCursor;
if (!SomeOperation())
{
WaitCursor.Restore();
MessageBox("не получилось :(");
}
}Обидно, да? А не восстановим - получим MessageBox не с тем курсором.Вот тут-то и приходит на помощь старый добрый оператор запятая. Трюк в чем: при вычислении выражения все его аргументы живут до конца вычисления всего выражения. Построим выражение, где у нас будет "думающий" курсор и наша операция:
if (WTL::CWaitCursor(), !SomeOperation())
MessageBox("не получилось :(");
Подписаться на:
Сообщения (Atom)