[英]how to create guard similar to boost::lock_guard
I want to create a guard, which locks a function on construction and unlocks it on destruction, eg calling the function with false
and true
. 我想创建一个防护,该防护在构造时锁定功能,在破坏时解锁功能,例如,使用false
和true
调用功能。
class A {
void enable( bool flag );
};
within another method, I want to use: 在另一种方法中,我想使用:
A::anotherMethod( ... ) {
block_guard(A::enable); // now A::enable(false)
// some operation
} // now A::enable(true)
my ideas: 我的想法:
using template 使用模板
template < class T >
class block_guard {
T t_;
public:
block_guard( T& t ) : t_(t) {
t_(false);
}
~block_guard() {
t_(true);
}
};
the question is, how to instantiate the template? 问题是,如何实例化模板? maybe with boost::bind
? 也许与boost::bind
?
using boost::function 使用boost :: function
class block_guard {
typedef boost::function< void (bool) > T;
T t_;
public:
block_guard( T& t ) : t_(t) {
t_(false);
}
~block_guard() {
t_(true);
}
};
this works fine, but the call seems to be very complicated with 这个工作正常,但是调用似乎非常复杂
block_guard bg(boost::function< void (bool) >(boost::bind(&A::enable, pointer-to-A, _1));
any ideas? 有任何想法吗? maybe there is another, much simpler way? 也许还有另一种更简单的方法?
First, realize that the member function is not all you need; 首先,意识到成员函数并不是您所需要的; you also need the object to invoke it on. 您还需要对象来对其进行调用。 There is no way in C++ for an object created in a function to implicitly capture the current this
pointer. 在C ++中,无法通过函数创建的对象隐式捕获当前的this
指针。
I'm going to assume you don't have C++11 available. 我将假设您没有C ++ 11。 If you do, using your second solution with a lambda expression is easiest. 如果这样做,使用带有lambda表达式的第二个解决方案是最简单的。
Now, if you don't care about the slight performance hit of boost::function (and you shouldn't), the second solution is good, but I would modify it slightly to make it more convenient to use by pulling the bind into the constructor. 现在,如果您不关心boost :: function的轻微性能下降(并且您不应该这样做),第二种解决方案很好,但是我会对其进行一些修改,以通过将bind插入其中来使其更方便使用。构造函数。
class block_guard {
typedef boost::function< void (bool) > block_fn;
block_fn block_fn_;
public:
// For non-member functions and function objects:
template <typename Fn>
block_guard(Fn fn) : block_fn_(fn) {
block_fn_(false);
}
// For member functions:
template <typename T, typename Ret>
block_guard(T* obj, Ret (T::*fn)(bool)) : block_fn_(boost::bind(fn, obj, _1)) {
block_fn_(false);
}
~block_guard() {
block_fn_(true);
}
};
Usage: 用法:
block_guard guard(this, &A::enable);
I use a Ret parameter here because there's no reason not to allow functions that return something - the return value will simply get ignored. 我在这里使用Ret参数是因为没有理由不允许函数返回某些东西-返回值将被忽略。
If you don't want boost::function, the thing will get less easy to use, because you have to template the block guard. 如果您不想使用boost :: function,那么事情将变得不那么容易使用,因为您必须模板化块防护。 It becomes useful to make a block_guard specifically for member functions then. 然后,专门为成员函数创建一个block_guard很有用。 You also lose the ability to use non-void functions. 您还将失去使用非无效函数的能力。
template <typename T>
class block_guard {
typedef void (T::*block_fn)(bool);
T* obj_;
block_fn block_fn_;
public:
block_guard(T* obj, block_fn fn) : obj_(obj), block_fn_(fn) {
(obj_->*block_fn_)(false);
}
~block_guard() {
(obj_->*block_fn_)(true);
}
};
Usage: 用法:
block_guard<A> guard(this, &A::enable);
Yes, there is a much simpler way, forget templates, generic thing and whatever not necessary and focus on the task. 是的,有一种简单得多的方法,忘记模板,通用的东西以及任何不必要的东西,而将精力集中在任务上。
All you need is a class with a ctor and a dtor. 您所需要的只是一门带有ctor和dtor的类。 Write the dtor first, it reveals what you will need to work. 首先编写dtor,它揭示了您需要进行的工作。 Then write the ctor, taking arguments as needed. 然后编写ctor,根据需要接受参数。 Lastly make the unwanted functions deleted (cctor, op=). 最后,删除不需要的功能(cctor,op =)。 Done. 完成。
Not generic, but straight to the point. 不是通用的,而是直截了当。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.