Scope Guard средствами C++0x: часть 2
Более глубокое погружение в C++0x
В прошлой части была рассмотрена реализация Scope Guard средствами C++0x. Благодаря шаблонам с переменным количеством параметров (variadic templates), реализация на C++0x получилась несколько проще, чем в оригинале, так как один и тот же шаблонный класс может использоваться для создания Scope Guard с различным количеством параметров.
Но, как было отмечено, предыдущая реализация не являлась оптимальной в плане количества строк. Можно сделать проще и короче.
Одна из проблем предыдущей реализации — необходимость наличия отдельного класса, если Scope Guard потребуется вызывать метод какого-либо класса.
Иными словами, требуется две реализации: одна для Scope Guard, работающего с обычными функциями, другая — для Scope Guard, работающего с методами. Как оказалось, данная проблема решаема.
Основную (на мой взгляд) неочевидность в коде создавал метод развёртки std::tuple (Apply_Helper).
Хорошая новость заключается в том, что благодаря std::bind() обе проблемы очень легко решаются.
Реализация XGuard теперь сильно упрощается:
class XGuard {
public:
XGuard(Function aFunction)
: m_fSucceeded{false}, m_Function(aFunction)
{
}
~XGuard(void)
{
if (!this->m_fSucceeded) {
try {
this->m_Function();
}
catch(...) {
}
}
}
XGuard(const XGuard&& other) : m_fSucceeded(other.m_fSucceeded), m_Function(other.m_Function)
{
other.commit();
}
void commit(void) const throw()
{
this->m_fSucceeded = true;
}
private:
mutable bool m_fSucceeded;
Function m_Function;
XGuard(const XGuard&) = delete;
XGuard& operator=(const XGuard&) = delete;
};
А благодаря type inference очень легко написать функцию, которая будет создавать XGuard:
auto makeXGuard(F f, const A&&... p) -> XGuard<decltype(std::bind(f, p...))>
{
auto func = std::bind(f, p...);
return XGuard<decltype(func)>(func);
}
Фокус в том, что передавая в функцию parameter pack (который const A&&... p), мы не можем априорно знать, какой результат вернёт std::bind() для таких аргументов. Использование вывода типов и альтернативный синтаксис функций приходят на помощь, в результате чего мы получили такой код.
Для возможности работы с методами классов нужно создать еще один вариант makeXGuard():
auto makeXGuard(C& c, M m, const A&&... p) -> XGuard<decltype(std::bind(m, c, p...))>
{
auto func = std::bind(m, c, p...);
return XGuard<decltype(func)>(func);
}
Вот так всё просто.
Автор: Vladimir; опубликовано в: C/C++; метки: C++0x, C/C++, Scope GuardАпр
2010
Комментарии к статье «Scope Guard средствами C++0x: часть 2» (4) »
Пожалуйста, не используйте эту форму для комментирования! Данная форма предназначена исключительно для ботов.
Оставить комментарий к записи «Scope Guard средствами C++0x: часть 2»
गते गते पारगते पारसंगते बोधि स्वाहा
Меня зовут Владимир, я программист-фрилансер, специализирующийся на Web-программировании и програмировании под Linux.
По совместительству занимаюсь администрированием LAMP/LNMP-серверов и техническим переводом.


[...] This post was mentioned on Twitter by Интернет заработок. Интернет заработок said: V.Kolesnikov: Scope Guard средствами C++0x: часть 2 [...]
Как же это не похоже на тот C++, что я знаю
Поскорей бы Бьерн выпустил новую книжку … Возможно тогда мне такой код станет очевидным
Так стандарт еще окончательно не принят
Так что придётся ждать.
Но если английский язык не является помехой, то рекомендую Wikipedia и этот замечательный FAQ.
А мне нравится программирование)) Правда больше по C++ Builder специализируюсь)). Даже пару миниигр делал…. Да и не очень он и сложен я бы даже сказал.