I want to create a guard, which locks a function on construction and unlocks it on destruction, e.g. calling the function with false and 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?
using 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.
I'm going to assume you don't have C++11 available. If you do, using your second solution with a lambda expression is easiest.
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.
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.
If you don't want boost::function, the thing will get less easy to use, because you have to template the block guard. It becomes useful to make a block_guard specifically for member functions then. 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. Write the dtor first, it reveals what you will need to work. Then write the ctor, taking arguments as needed. Lastly make the unwanted functions deleted (cctor, op=). Done.
Not generic, but straight to the point.
Related
I'm not sure what I am asking for is possible.
I have a templated class called Controller. This is a variadic template class which takes multiple classes and can set their values as such.
Controller<ClassA,ClassB,ClassC>* myController = new Controller<ClassA,ClassB,ClassC>(*a,*b,*c);
myController->setValues(32);
This takes a bunch of different classes together and allows me to to set their values at the same time. setValues is a templated function which allows any type to be passed in. However, right now I am trying to modify my class so that I can set a value within the controller itself for easy retrieval. However this is the part that is proving difficult.
template<typename...Classes>
class Controller
{
public:
Controller(Classes&...objects) : objects(objects...){}
Controller(std::tuple<Classes&...> tup) : objects(tup){}
template<typename T>
void setValues(T value)
{
std::apply([&](auto&...x) { x.updateValue(value),...);}, objects); //calls the updateValue function for each class
}
private:
std::tuple<Classes&...> objects;
};
I want to add the following as a private variable T controllerValue; However, I know that I cannot simply declare T because we cannot define member templates and the compiler has no idea what to expect. Which then I tried to create a private struct:
template<typename T>
struct ControllerValue { T value; };
However, I cannot define a struct underneath that, because the same problem occurs. The compiler has no idea what type ControllerValue is. What I would like is something like this:
template<typename...Classes>
class Controller
{
public:
Controller(Classes&...objects) : objects(objects...){}
Controller(std::tuple<Classes&...> tup) : objects(tup){}
template<typename T>
void setValues(T value)
{
thisValue.value = value;
std::apply([&](auto&...x) { x.updateValue(value),...);}, objects); //calls the updateValue function for each class
}
template<typename T>
T getValue() const { return thisValue.value }
private:
std::tuple<Classes&...> objects;
template<typename T>
struct ControllerValue { T value; };
ControllerValue thisValue;
};
This will not compile at all for the same reason that the compiler has no idea what type ControllerValue should be. And this is where I am stuck. Is this even possible to do? If not, what is another way that I can make this work?
To clear up confusion, the use case would be something like this:
Controller<ClassA,ClassB,ClassC>* myController = new Controller<ClassA,ClassB,ClassC>(*a,*b,*c);
myController->setValues(32);
int commonValue = myController->getValue();
or
Controller<ClassA,ClassB,ClassC>* myController = new Controller<ClassA,ClassB,ClassC>(*a,*b,*c);
myController->setValues(32.3);
double commonValue = myController->getValue();
I think solving this exact problem is impossible in C++ (and still very cumbersome in languages with runtime generics). You can very easily create a polymorphic class that can only store any value:
class PolymorphicBase
{
public:
virtual ~PolymorphicBase() = default;
};
template <class T>
class PolymorphicObject : public PolymorphicBase
{
T value;
public:
PolymorphicObject(T value) : value(std::move(value))
{
}
};
A member of std::unique_ptr<PolymorphicBase> can sufficiently store any value, but how would such a value be retrieved? Probably the easiest is to expose the reference to PolymorphicBase and use dynamic type checks to see if the type is compatible with something you know, but what if you need the code to work for any type?
This is what lambdas with auto parameters are useful for. However, you would have to be able to pass such a lambda to a method on PolymorphicBase and implement that method in PolymorphicObject. This is impossible, since you cannot override a method template (it needs to be a template to accept a lambda) – that's where the compile-time and runtime parts of C++ clash. And there is simply no type in C++ that represents a function accepting any parameter (and knowing its type), which is a template by itself.
You can partially solve this by making the type of the lambda known to PolymorphicBase:
template <class Retriever>
class PolymorphicBase
{
public:
virtual void retrieve(Retriever func) = 0;
virtual ~PolymorphicBase() = default;
};
template <class Retriever, class T>
class PolymorphicObject : public PolymorphicBase<Retriever>
{
T value;
public:
PolymorphicObject(T value) : value(std::move(value))
{
}
void retrieve(Retriever func) override
{
func(value);
}
};
auto lambda = [](auto arg)
{
std::cout << arg << std::endl;
};
PolymorphicObject<decltype(lambda), int> obj(6);
PolymorphicBase<decltype(lambda)> &ptr = obj;
ptr.retrieve(lambda);
This is useful if you ever have only a single way to retrieve the value.
I don't think this is needed in most cases anyway. Usually you use a fixed set of types as the values, so you can use a variant there, or they all implement a common interface, or (as you've pointed out in the comments) you actually meant to move the type parameter from the method to the class (which allows you to check that all the types actually support the value earlier than originally).
However, I agree that in languages with generics/templates it is somewhat hard to have a method that can actually choose its result type in a generic fashion, without being controlled by outside parameters.
Consider the following code snippet.
template <T>
MyPtr<T> CreateObject()
{
// Do something here first...
// return our new object
return MyPtr<T>(new T());
}
class Foo
{
private:
Foo() { }
public:
static MyPtr<Foo> GetNewInstance()
{
// ERROR: Foo is private...
return CreateObject<Foo>();
}
};
class Bar
{
public:
Bar() { }
};
int main()
{
MyPtr<Bar> bar = CreateObject<Bar>();
return 0;
}
Without resorting to macro for CreateObject (I like the syntax of MyPtr<type> obj = CreateObject<type>(params)), is there a way to make the function CreateObject share the same context as the caller function, thus able to access private Foo c'tor? 'friend' is not what I'm looking for as it would mean anyone calling CreateObject would have access to private Foo c'tor, which is not what I want. Overloading the new operator wouldn't work either as it is imperative that a MyPtr is returned instead of just T* (by assigning T* to MyPtr assigns a type to the object that is required somewhere else).
I guess what I'm looking for is something in between a macro and a template function (syntax of a template function but gets expanded fully like a macro). It would be quite useful to have this feature in this particular case.
Well, you could do that with the passkey pattern:
template<class T, class PassKey>
MyPtr<T> CreateObject(PassKey const& key)
{
return new T(key);
}
class FooKey{
private:
FooKey(){} // private ctor
FooKey(const FooKey&); // undefined private copy ctor
friend class Foo;
};
class Foo{
public:
// public ctor
Foo(FooKey const&){}
static MyPtr<Foo> GetNewInstance()
{
return CreateObject<Foo>(FooKey());
}
};
Example at Ideone.
With C++0x, this can be done much easier than creating a new Key struct every time, since template parameters are now allowed to be friends:
template<class T>
struct PassKey{
private:
PassKey(){}
PassKey(const PassKey<T>&);
friend T;
};
This is basically the same as attempting to use make_shared with a private constructor.
The only way to allow this is with friend. You're pretty much stuck in this case I'm afraid.
I am not sure as to what you are trying to achieve. The simplification to post the problem here has taken away the actual need for the whole thing. So I will just assume that you know what you are doing, and that you really need this (and I suggest that you rethink whether you do need it, as I don't see a point...)
At any rate, you can solve the problem by passing a creator callback to the CreateObject template:
template <typename T, typename Creator>
MyPtr<T> CreateObject( Creator creator )
{
// Do something here first...
return MyPtr<T>(creator());
}
class Foo
{
private:
Foo() {}
static Foo* create() { return new Foo(); }
public:
static MyPtr<Foo> GetNewInstance() {
return CreateObject<Foo>( &Foo:create );
}
// ...
};
The actual issue though, is what does Do something here first actually does that forces you into this complex creation patterns. The fact that it has to be executed before the creation of the new object seems to indicate that there are hidden dependencies not shown in the code, and that usually end up in maintenance nightmares, where someone down the line reorders some code, or adds a new constructor and everything seems to fall apart. Revisit your design and consider whether those dependencies can be simplified or made explicit.
Since you are newing up the object in the very end it really doesn't relate to your CreateObject function. So Change the function prototype to:
template <typename T>
MyPtr<T> CreateObject(T* const p)
{
//...
return MyPtr<T>(p);
}
Usage:
static MyPtr<Foo> GetNewInstance()
{
return CreateObject(new Foo());
}
is there a way to make the function CreateObject share the same context as the caller function
Yes, pass the context you need as an argument (either as an argument to the template, or as an argument to the function).
In practice, move the new T call to a separate function (or struct template, as I chose to do here), like this:
// Dummy representation of your pointer type
template <typename T>
struct MyPtr
{
MyPtr( T *p ) { }
};
// Default constructor template; may be specialized to not use "new" or so.
template <typename T>
struct Constructor
{
static T *invoke() { return new T; }
};
// Needs to be a struct (or class) so 'C' can have a default value
template <typename T, typename C = Constructor<T> >
struct CreateObject
{
MyPtr<T> operator()() {
return MyPtr<T>( C::invoke() );
}
};
class Foo
{
private:
friend struct Constructor<Foo>;
Foo() { }
public:
static MyPtr<Foo> GetNewInstance()
{
return CreateObject<Foo>()();
}
};
If you want to handle different constructor signatures (read: if not all types T have the same constructor signature), you could also choose to not pass the Constructor as a template to the CreateObject struct, but instead use a function argument. That way, you could 'load' a Constructor like this:
// ...
static MyPtr<Foo> GetNewInstance()
{
Constructor<Foo> c( arg1, arg2, arg3 );
return CreateObject<Foo>( c );
}
Example first:
template <class HashingSolution>
struct State : public HashingSolution {
void Update(int idx, int val) {
UpdateHash(idx, val);
}
int GetState(int idx) {
return ...;
}
};
struct DummyHashingSolution {
void UpdateHash(int idx, int val) {}
void RecalcHash() {}
};
struct MyHashingSolution {
void UpdateHash(int idx, int val) {
...
}
void RecalcHash() {
...
UpdateHash(idx, GetState(idx)); // Problem: no acces to GetState function, can't do recursive application of templates
...
}
};
In this example I can pass MyHashingSolution to State class so State have access to HashingSolution's methods, but HashingSolution can't call GetState. Is it possible to work around this?
This is in the deepest loop. virtual function here drops the performance by more than 25%.
Inlineing is crucial for me.
As jalf suggests in the comments, you probably want to use a variant of the Curiously Recurring Template Pattern (CRTP). That is, make MyHashingSolution a class template parametrised by the derived class:
template <typename D>
struct MyHashingSolution {
typedef D Derived;
void UpdateHash(int idx, int val) {
...
}
void RecalcHash() {
...
UpdateHash(idx, derived().GetState(idx));
...
}
private:
// Just for convenience
Derived& derived() { return *static_cast<Derived*>(this); }
};
In this case, because you want the derived State class to also be a template, you need to take the slightly unusual step of declaring State as a class template that takes a template template parameter:
template <template <class T> class HashingSolution>
struct State : public HashingSolution<State<HashingSolution> > {
typedef HashingSolution<State<HashingSolution> > Parent;
void Update(int idx, int val) {
Parent::UpdateHash(idx, val); // g++ requires "Parent::"
}
int GetState(int idx) {
return ...;
}
};
The key point is that, provided State inherits from HashingSolution<State<HashingSolution> >, Derived is a derived class of HashingSolution<State<HashingSolution> > so the static_cast<Derived*>(this) downcast in HashingSolution<State>::derived() compiles and works correctly. (If you mess up and derive State from HashingSolution<SomeOtherType> instead and then try something that involves a call to derived(), the compiler will complain as the requirements for static_cast<> are not met.)
Then declare the concrete State class you want to use like so:
typedef State<MyHashingSolution> MyState;
Unfortunately this solution has the side effect that you will need to change DummyHashingSolution (and any other such types) to templates that ignore their one template argument, in order to make them usable as template template arguments.
As a shot in the dark, considering the almost complete lack of information in the question (see comments): would templates be useful? They're often good for compile-time polymorphism.
To get any more potentially useful information, please explain the problem more. Look at the problem comments. Tell us why you know what micro-optimizations need to be made when you're still working on fundamental design. If there's anything non-mainstream about the compilation or execution environments, give us a few details.
I'm working on a resource management class and want to have the user provide a functor to a "ReleaseResource" method as part of the resource manager's constructor. From there when a resource is requested that functor will be provided as the deleter for the shared_ptr that I will be returning so that the appropriate method will be called when the resource is no longer used.
The problem I'm running into that this requires me to store the functor in my class, and I'm not entirely sure how to do that. Typically when using a functor you template the function like so:
template<class MyFunctor> MyMethod(MyFunctor f) {
f();
}
Which is great if you intend to use the functor in the scope of that function, but since the template goes out of scope with the function I'm not sure how you would specify a variable of the appropriate type to store the functor for later use.
Can anyone point me in the right direction here?
template<class MyFunctor> MyMethod(MyFunctor f) {
boost::function<void()> g = f;
g();
}
The type you pass to boost::function is the function type. For example, int(bool, char) is the type of a function returning int and taking a bool and a char. That said, if you want to construct the shared_ptr right away, you don't need to store the functor somewhere (boost::function requires the new operator for that, even though for very small functors, it will use special tricks to only use stack allocation (small buffer optimization)):
template<class MyFunctor> MyMethod(MyFunctor f) {
boost::shared_ptr<T> ptr(new T, f);
}
boost::function is part of tr1 and will be part of the next official C++ Standard. Example:
struct Manager {
template<typename Deleter>
Manager(Deleter d)
:deleter(d) {
}
boost::shared_ptr<Resource> allocate() {
...
return boost::shared_ptr<Resource>(resource, deleter);
}
private:
boost::function<void(Resource *)> deleter;
};
There are two ways, both of which biol down to templating the class.
template <MyFunctor>
class MyClass
{
MyFunctor func;
public:
MyClass(MyFunctor f) :func(f)
{ }
MyMethod()
{
func();
}
}
This would require you to know the type of the functor. To avoid that, we can use a factory:
template<MyFunctor>
MyClass<MyFunctor> MakeFunctorClass(MyFunctor f)
{
return MyClass<MyFunctor>(f);
}
Alternately, since in all likelihood, most of the functor signature will be the same, with only a small part changing, we could use that:
template <MyType>
class MyClass
{
typedef std::binary_function<MyType, MyType, bool> MyFunctor;
MyFunctor func;
public:
MyMethod(MyFunctor f)
{
func = f;
func();
}
}
This makes usage a bit simpler:
bool AreEqual(int, int);
MyClass<int> myc;
myc.MyMethod(AreEqual);
at the expensive of a trickier definition (i.e., I don't guarantee that the binary_function typedef I gave will work)
Not sure if this would help, but be aware that boost::shared_ptr has constructor overrides which allow the user to include a custom de-allocation (and custom allocator, if desired). This might be sufficient for what you need (it's designed with that in mind, if I'm reading your use-case correctly).
C++ has so much stuff that I don't know.
Is there any way to create a function within a class, that will always be called whenever any other function of that class is called? (like making the function attach itself to the first execution path of a function)
I know this is tricky but I'm curious.
Yes-ish, with a bit of extra code, some indirection and another class and using the -> instead of the . operator.
// The class for which calling any method should call PreMethod first.
class DogImplementation
{
public:
void PreMethod();
void Bark();
private:
DogImplementation(); // constructor private so can only be created via smart-pointer.
friend class Dog; // can access constructor.
};
// A 'smart-pointer' that wraps a DogImplementation to give you
// more control.
class Dog
{
public:
DogImplementation* operator -> ()
{
_impl.PreMethod();
return &_impl;
}
private:
DogImplementation _impl;
};
// Example usage of the smart pointer. Use -> instead of .
void UseDog()
{
Dog dog;
dog->Bark(); // will call DogImplementation::PreMethod, then DogImplementation::Bark
}
Well.. something roughly along those lines could be developed into a solution that I think would allow you to do what you want. What I've sketched out there probably won't compile, but is just to give you a starting point.
Yes. :-)
Wrap the object in a smart pointer
Invoke the object's special function automatically from the smart pointer's dereferencing operators (so that the special function is invoked whenever a client dereferences the smart pointer).
You can derive from this class template:
namespace detail {
struct const_tag;
struct nonconst_tag;
/* T is incomplete yet when pre_call is instantiated.
* so delay lookup of ::impl until call to operator->
* happened and this delay_lookup is instantiated */
template<typename U, typename>
struct delay_lookup;
template<typename U>
struct delay_lookup<U, nonconst_tag>
{
typedef typename U::template get_impl<
typename U::derived_type>::type impl_type;
impl_type* u;
delay_lookup(impl_type* u):u(u) { }
impl_type* operator->() { return u; }
};
template<typename U>
struct delay_lookup<U, const_tag> {
typedef typename U::template get_impl<
typename U::derived_type>::type const impl_type;
impl_type* u;
delay_lookup(impl_type* u):u(u) { }
impl_type* operator->() { return u; }
};
} // detail::
template<typename T>
struct pre_call {
private:
friend class detail::delay_lookup<pre_call, detail::const_tag>;
friend class detail::delay_lookup<pre_call, detail::nonconst_tag>;
typedef T derived_type;
/* pre_call is the friend of T, and only it
* is allowed to access T::impl */
template<typename U> struct get_impl {
typedef typename U::impl type;
};
protected:
typedef boost::function<void(T const&)> fun_type;
fun_type pre;
template<typename Fun>
pre_call(Fun pre):pre(pre) { }
public:
/* two operator->: one for const and one for nonconst objects */
detail::delay_lookup<pre_call, detail::nonconst_tag> operator->() {
pre(*get_derived());
return detail::delay_lookup<pre_call,
detail::nonconst_tag>(&get_derived()->d);
}
detail::delay_lookup<pre_call, detail::const_tag> operator->() const {
pre(*get_derived());
return detail::delay_lookup<pre_call,
detail::const_tag>(&get_derived()->d);
}
private:
T * get_derived() {
return static_cast<T *>(this);
}
T const* get_derived() const {
return static_cast<T const*>(this);
}
};
And use it like this:
struct foo : pre_call<foo> {
private:
/* stuff can be defined inline within the class */
struct impl {
void some() const {
std::cout << "some!" << std::endl;
}
void stuff() {
std::cout << "stuff!" << std::endl;
}
};
void pre() const {
std::cout << "pre!" << std::endl;
}
friend struct pre_call<foo>;
impl d;
public:
foo():pre_call<foo>(&foo::pre) { }
};
int main() {
foo f;
f->some();
f->stuff();
// f.some(); // forbidden now!
}
Previously i had a version that called post functions too. But i dropped it. It would have needed additional work. However, i would still not recommend you to do this "call function automatically" thingy. Because one can easily forget to use the operator-> syntax and just use the dot - and suddenly have the pre function not called
Update: The version above takes care of that, so one cannot accidentally call functions with the dot anymore.
There is no "automatic" way to do this. You would need to add a call to the function in each class method.
Without some insane code injection, this is not possible. However, you can of course call that function manually.
The short answer: No.
The long answer: there is no such thing in the C++ standard.
If I'm not mistaken this is a feature of what is called Aspect Oriented Programming.
As others have said, there is no "automatic" way to do this. As in, the C++ standard does not define a way to do this.
However, if you are going to go the route of putting a method call at the beginning of every method, I would recommend you instead store and invoke a method pointer instead. This will allow you to dynamically modify which method is being called, including none with some careful programming and setting the method to null.
I'm not sure exactly what your restrictions are, so I don't know if this helps.
If your object a singleton, you could stick all the code that gets called for every function call in the call to get the singleton.
Downside is all your other functions calls get ugly. And you may not be able to make the object a singleton.