I try to use a "simple" signal system with C++ 11. I use the following class :
http://geekswithblogs.net/raccoon_tim/archive/2011/09/28/lambdas-and-events-in-c.aspx
but I have a problems (I use Visual Studio 2012):
Problem description
I cannot create an event like this :
RREvent1Arg<void> testEvent;
The "void" is not an argument type !!
I have try with "template specialization" something like :
template<typename T1, typename T2> class Signaler {};
template<> class Signaler<T1> {};
template<> class Signaler<void> {};
But I got some compilation problems:
error C2065: 'T1' : undeclared identifier
Thanks for your help
Answer 1:
This RREvent1Arg from your article is not a general purpose signal/slot system. It isn't written in a generalized way. It's not surprising it hasn't been written to accommodate void, just as it isn't surprising that it doesn't handle a number of arguments besides 1 (given the name).
Note that it defines the callback handler as typedef std::function<void (T1)> Func; and then later tries to define things like void Call( T1 arg ). You can't declare a function in source like void foo( void arg ) in C++, and templates aren't allowed to create those either. There would be ways of using overloading to fix this, but there are also ways of taking variable arguments, etc.
Answer 2:
Offhand I'm not exactly sure what the rules are for using the capture features of lambda on "this" are, especially if it's getting wrapped up as a std::function. And because it's confusing I'd suggest saving this into another local variable, and capturing that by value:
static RREvent1Arg<int> testEvent;
class MyClass
{
int a;
void MyMethod()
{
MyClass *mc = this;
testEvent += [=mc](int) { mc->SignalReceived(); };
}
void SignalReceived()
{
this->a = 10;
}
};
But that's just me. Maybe the this capture is good style. Seems to cause problems for people in other questions.
I wrote this "simple signal library" that I use for a bunch of projects:
http://bitbucket.org/danielko/simplesignal
It doesn't handle accumulation of returned values because I don't consider that use case to be common enough to warrant the extra complexity.
What it does implement though is the signal/slot semantics; when you connect, you get a slot back that you need to keep alive for as long as you want to receive notifications from the signal. Destroying the slot (or calling disconnect() on it) will stop the signal from being delivered to the owner of the slot.
Hopefully it's simple and readable enough to be understandable; variadic templates take care of any number of arguments, no need for specialization.
Related
The example below is a minimal, maybe not so good example of a well known idiom.
It compiles and it is so ugly in order to be able to maintain it minimal, because the question is not about the idiom itself.
struct Foo {
virtual void fn() = 0;
};
template<class T>
struct Bar: public Foo {
void fn() override {
T{}.fn();
}
};
struct S {
void fn() { }
};
int main() {
Foo *foo = new Bar<S>{};
foo->fn();
}
What I'm struggling with since an hour ago is how to change it (or even, if there exists an alternative idiom) to introduce a variadic template member method.
Obviously, I cannot modify the fn function of the Foo class, because it's a virtual one and virtual specifier doesn't goes along with templates. The same is valid for the fn specification of Bar, because it has to override somehow the one in the base class.
Note.
For I strongly suspect that this question could be one of the greatest XYProblem ever seen, I'd like also to give a brief description of the actual problem.
I have a class that exposes two templated member methods:
the first one accepts a template class T that is not used immediately, instead it should be stored somehow in order to be used later.
the second one accepts a variadic number of arguments (it is actually a variadic templated member function) and those arguments should be perfectly forwarded to a newly created instance of T.
Well, the problem is far more complex, but this is a good approximation of it and should give you an idea of what's the goal.
Edit
I guess that it is somehow similar to higher order functions.
I mean, what would solve the problem is indeed a templated function to which to bind the first argument, but as far as I know this is impossible as well as any other approach I've explored so far.
Any viable solution that expresses the same concept?
What I mentioned in the comments is the following approach:
template<typename T> class Factory {
public:
template<typename ...Args>
auto construct(Args && ...args)
{
return T(std::forward<Args>(args)...);
}
};
So now, your first exposed class method will be something like this:
template<typename T>
auto getFactory() {
return Factory<T>();
}
So:
auto factory=object.getFactory<someClass>();
// Then later:
factory.construct(std::string("Foo"), bar()); // And so on...
Instead of construct() you could use operator() too, so the second part of this becomes, simply:
factory(std::string("Foo"), bar()); // And so on...
As I mentioned, this is not really type erasure. You can't use type erasure here.
Having given this a few minutes' more thought, the reason that type erasure cannot be used here is because a given instance of type erasure must be "self contained", or atomic, and what you need to do is to break atomic type erasure into two parts, or two class methods, in your case.
That won't work. Type erasure, by definition, takes a type and "erases" it. Once your first function type-erases its class method template parameter, what you end up with is an opaque, type-erased object of some kind. What was type-erased is no longer available, to the outside world. But you still haven't type-erased your constructor parameters, which occurs somewhere else.
You can type-erase the template class, and the constructor parameters together. You can't type-erase the template class, and the constructor parameters, separately and then somehow type-erase the result again.
The simple factory-based approach, like the one I've outlined, would be the closest you can get to results that are similar to type erasure, if both halfs of your desired type-erasure appear in the same scope, so you can actually avoid type-erasure, and instead rely on compiler-generated bloat.
I also agree that you cannot do exactly what you want here. I will post what I think the closest option is (at least a close option that is different from SamVarshavchik's answer).
I don't expect this answer to solve your problem exactly, but hopefully it will give you some ideas.
struct Delay // I have no idea what to call this
{
template <class T>
void SetT()
{
function_ = [](boost::any params){return T(params);}
}
template <class ... Args>
boost::any GetT(Args ... args)
{
return function_(std::make_tuple(args...));
}
private:
std::function<boost::any(boost::any)> function_;
};
The obvious limitation of this is that anyone calling GetT will somehow have to know what T was already, though you can query the boost::any object for the type_info of its class if that helps. The other limitation here is that you have to pass in T's that take a boost::any object and know what to do with it. If you cannot have T do that, then you can change SetT (or create a new member function) like this:
template <class F>
SetTFactory(F f)
{
function_ = f;
}
and then use it like:
Delay d;
d.SetTFactory([](boost::any s){return std::string(boost::any_cast<const char*>(s));});
auto s = d.GetT("Message");
assert(s.type() == typeid(std::string));
This of course introduces a whole new set of difficulties to deal with, so I don't know how viable this solution will be for you. I think regardless of anything else, you're going to have to rethink your design quite a bit.
I'm trying to construct a work queue of functions that need to be executed by one thread and can be fed by many threads. To accomplish this, I was planning on using the boost::packaged_task and boost::unique_future. The idea would be you would do:
Foo value = queue.add(myFunc).get();
which would block, until the function is executed. So queue.add(...) takes in a boost::function, and returns a boost::unique_future. Internally it then creates a boost::packaged_task using the boost::function for its constructor.
The problem I'm running into is that boost::function<...> won't be the same every time. Specifically, the return value for it will change (the functions, however, will never take any parameters). Thus, I have to have an add function that looks something like:
template <typename ResultType>
boost::unique_future<ResultType> add(boost::function<ResultType ()> f) {
boost::packaged_task<boost::function<ResultType ()> > task(f);
queue.push_back(task);
return task.get_future();
}
Okay, that doesn't seem too bad, but then I ran into the problem of how to define 'queue'. I think I have no choice but to use boost::any, since the types will not be constant:
std::list<boost::any> queue; // note: I'm not concerned with thread-safety yet
But then I run into a problem when I try to implement my executeSingle (takes just a single item off the queue to execute):
void executeSingle() {
boost::any value = queue.back();
boost::packaged_task<?> task = boost::packaged_task<?>(boost::move(value));
// actually execute task
task();
queue.pop_back();
}
The '?' denote what I'm unsure about. I can't call executeSingle with a template, as it's called from a separate thread. I tried using boost::any, but I get the error:
conversion from 'boost::any' to non-scalar type boost::detail::thread_move_t<boost:thread>' requested.
The funny part is, I actually don't care about the return type of packaged_task at this point, I just want to execute it, but I can figure out the template details.
Any insight would be greatly appreciated!
You should store boost::function<void()>'s. Note that boost::packaged_task<R>::operator() doesn't return anything; it populates the associated boost::future. In fact, even if it returned something you could still use boost::function<void()> since you'd still have no interest in the returned value: all you care about is to call queue.back()(). If this were the case boost::function<void()>::operator() would take care of discarding the returned value for you.
As a minor note, you might want to change the signature of your add method to be templated on a generic type Functor rather than a boost::function, and use boost::result_of to get the result type for boost::packaged_task.
My suggestion as a whole:
template<typename Functor>
boost::future<typename boost::result_of<Functor()>::type>
queue::add(Functor functor) // assuming your class is named queue
{
typedef typename boost::result_of<Functor()>::type result_type;
boost::packaged_task<result_type> task(functor);
boost::unique_future<result_type> future = task.get_future();
internal_queue.push_back(boost::move(task)); // assuming internal_queue member
return boost::move(future);
}
void
queue::executeSingle()
{
// Note: do you really want LIFO here?
queue.back()();
queue.pop_back();
}
EDIT
How to take care of move-semantics inside queue::add
typedef typename boost::result_of<Functor()>::type result_type;
typedef boost::packaged_task<result_type> task_type;
boost::shared_ptr<task_type> task = boost::make_shared<task_type>(functor);
boost::unique_future<result_type> future = task->get_future();
/* boost::shared_ptr is possibly move-enabled so you can try moving it */
internal_queue.push_back( boost::bind(dereference_functor(), task) );
return boost::move(future);
where dereference_functor could be:
struct dereference_functor {
template<typename Pointer>
void
operator()(Pointer const& p) const
{
(*p)();
}
};
You could also substitute the bind expression for the much clearer
boost::bind(&task_type::operator(), task)
which also doesn't require a custom functor. However if there are multiple overloads of task_type::operator() this might need disambiguation; the code could also break if a future change in the Boost.Thread introduce an overload.
You use old-fashioned virtual functions. Define a base class task_base with a virtual execute method, then define a template derived class which holds a specific task instance. Something along the lines:
struct task_base {
virtual void execute() = 0;
};
template<typename ResultType>
struct task_holder : task_base {
task_holder(boost::packaged_task<boost::function<ResultType ()> >&& task)
: m_task(task) { }
void execute() {
m_task();
}
private:
boost::packaged_task<boost::function<ResultType ()> > m_task;
};
And define your queue to hold unique_ptr<task_base>. This is essentially what boost::any does, only you'd be using a specific function, namely execute.
NOTE: Untested code! And I'm still not very familiar with rvalue references. This is just to give you the idea of how the code would look.
Somewhat belatedly, but you might want to consider using Boost.Asio instead of rolling your own queue-runner solution.
While this grew up as an I/O library it does support asynchronous calls just like this. Simply define an io_service somewhere, run it inside a thread, and then post functors to get called on that thread.
I'm making a Gui API for games. Basically I have event callbacks in my class which are function pointers. I thought of directly letting the user = the function pointer ex:
widget->OnPaintCallback = myPaintFunc;
But I don't like how I cannot check for NULL or do anything else. It also makes my class feel exposed.
I also thought of having a setter for each callback, but that will get messy in the class (I have over 50)
I then thought of a function that asks for a string indicating which event the handler is for, and its function pointer. But that would evolve needlessly referencing documentation to know the string, and even more confusing for custom undocumented widgets.
Is there a better, cleaner alternative?
Thanks
Could casablankca's solution have multiple arguments?
I would suggest the Boost.Signals library. Something like this:
class Widget
{
public:
boost::signal<void (Paint &)> onPaint;
boost::signal<void (MouseMove &)> onMouseMove;
// ... etc
};
// later...
Widget myWidget;
myWidget.onPaint.connect(myPaintFunc);
// and to fire the event:
void Widget::DoPaint()
{
Paint data;
data.whatever = foo;
onPaint(data);
}
This has several advantages:
You can combine it with boost::bind (or C++0x version of bind if your compiler supports it) to allow you to bind member functions to event handlers.
You can attach multiple handlers to a single event. If you just use function pointers, then only a single function pointer can be assigned at a time.
The signals are strong-typed and flexible. You can have signals which take different types and numbers of parameters, and they'll all be resolved at compile-time.
I recommend taking a look at the boost.signals library, or libsigc++. These are very general libaries for managing things like event handlers. They do a lot more than what you are trying to do, but they'll give you ideas for what you may want from your design that you haven't thought of yet.
The more you use your callbacks the more you'll realize that you want more of the features in those libraries (like registering multiple callbacks, binding arguments, being more flexible with types, etc.) So even if you end up doing something simpler, it will be helpful to learn from mature designs.
But I don't like how I cannot check for NULL or do anything else
How about making the callback (OnPaintCallback) an object of a class that overloads operator =, that way you can do any additional checking and throw an exception if something goes wrong. You can also overload operator () so that you can call this object as if it were a simple function pointer.
Update: As for variable number of function arguments, there is no general way to do it, but if your maximum N is limited and small, you could use template specializations, for example: (I've omitted constructors, operator = and other details for clarity)
template<typename T, int N>
class Callback {
};
template<typename T>
class Callback<T, 1> {
T func;
template<typename A1>
void operator ()(A1 arg1) {
func(arg1);
}
};
template<typename T>
class Callback<T, 2> {
T func;
template<typename A1, typename A2>
void operator ()(A1 arg1, A2 arg2) {
func(arg1, arg2);
}
};
I know this is a hacky way to do it but at least your users won't see any of this: they'll get the same interface for all callbacks.
You can do an interface for each type of event handler you need. Not unlike Java does it. So for example you would have
class PaintCallback {
public:
virtual void paint() = 0;
};
Your event handler would inherit from the abstract class and implement the paint method. In the widget class you would keep a pointer (or a collection) for each handler.
Say you have a sub class B which inherits from super class A. You want a function that can accept either A or B.
template <typename T>
void someFunc(T* pObj, bool someOtherArg)
{
pObj->AnInheritMethod();
if (pObj->IsASub())
{
pObj->ANonInhertMethod();
}
}
When I compile this (Visual Studio 6) I get:
error C2065: 'pObj' : undeclared identifier
Am I way off base here?
You don't need a function template for this; the following will do just fine:
void someFunc(A* pObj)
{
pObj->AnInheritMethod();
if (B* pObjAsB = dynamic_cast<B*>(pObj))
{
pObjAsB->ANonInheritMethod();
}
}
Or, if you prefer to use your IsASub() member function instead of dynamic_cast:
void someFunc(A* pObj)
{
pObj->AnInheritMethod();
if (pObj->IsASub())
{
B* pObjAsB = static_cast<B*>(pObj);
pObjAsB->ANonInheritMethod();
}
}
Aside from the missing return type, I don't see anything obviously wrong with the code in your example; I don't have Visual C++ 6 installed to check.
You don't need templates for that, that is a free behaviour courtesy of polymorphism.
Edit: also if you write something like:
if (pObj->IsASub())
then there's maybe something wrong in your design. The method is supposed to work for any type in the derivation chain.
You're asking a question that is completely unrelated to the code and error that you included.
In order to have a function take an A or a class derived from A, all it needs to do is take a pointer or reference to A, e.g.
someFunc(A* pObj, bool someOtherArg);
or
someFunc(A& obj, bool someOtherArg);
It will work by virtue of inheritance. That's kind of the whole point of deriving classes from each other. The way you have written it with templates, it will work with any class that defines the three methods you use, whether or not it derives from A.
Now the error you posted is unrelated to this question but is bizarre. There's nothing wrong with the code you posted, but Visual Studio 6 is an ancient compiler; it's twelve years old and does not fully support modern ISO standard C++. This error may be an artifact of a sub-standard templating implementation in the compiler.
Is there any template available in boost for RAII. There are classes like scoped_ptr, shared_ptr which basically work on pointer. Can those classes be used for any other resources other than pointers. Is there any template which works with a general resources.
Take for example some resource which is acquired in the beginning of a scope and has to be somehow released at the end of scope. Both acquire and release take some steps. We could write a template which takes two(or maybe one object) functors which do this task. I havent thought it through how this can be achieved, i was just wondering are there any existing methods to do it
Edit: How about one in C++0x with support for lambda functions
shared_ptr provides the possibility to specify a custom deleter. When the pointer needs to be destroyed, the deleter will be invoked and can do whatever cleanup actions are necessary. This way more complicated resources than simple pointers can be managed with this smart pointer class.
The most generic approach is the ScopeGuard one (basic idea in this ddj article, implemented e.g. with convenience macros in Boost.ScopeExit), and lets you execute functions or clean up resources at scope exit.
But to be honest, i don't see why you'd want that. While i understand that its a bit annoying to write a class every time for a one-step-aquire and one-step-release pattern, you are talking about multi-step-aquire and -release.
If its taken multiple steps, it, in my opinion, belongs in an appropiately named utility class so that the details are hidden and the code in place (thus reducing error probability).
If you weigh it against the gains, those few additional lines are not really something to worry about.
A more generic and more efficient (no call through function pointer) version is as follows:
#include <boost/type_traits.hpp>
template<typename FuncType, FuncType * Func>
class RAIIFunc
{
public:
typedef typename boost::function_traits<FuncType>::arg1_type arg_type;
RAIIFunc(arg_type p) : p_(p) {}
~RAIIFunc() { Func(p_); }
arg_type & getValue() { return p_; }
arg_type const & getValue() const { return p_; }
private:
arg_type p_;
};
Example use:
RAIIFunc<int (int), ::close> f = ::open("...");
I have to admit I don't really see the point. Writing a RAII wrapper from scratch is ridiculously simple already. There's just not much work to be saved by using some kind of predefined wrapper:
struct scoped_foo : private boost::noncopyable {
scoped_foo() : f(...) {}
~scoped_foo() {...}
foo& get_foo() { return f; }
private:
foo f;
};
Now, the ...'s are essentially the bits that'd have to be filled out manually if you used some kind of general RAII template: creation and destruction of our foo resource. And without them there's really not much left. A few lines of boilerplate code, but it's so little it just doesn't seem worth it to extract it into a reusable template, at least not at the moment. With the addition of lambdas in C++0x, we could write the functors for creation and destruction so concisely that it might be worth it to write those and plug them into a reusable template. But until then, it seems like it'd be more trouble than worth. If you were to define two functors to plug into a RAII template, you'd have already written most of this boilerplate code twice.
I was thinking about something similar:
template <typename T>
class RAII {
private:
T (*constructor)();
void (*destructor)(T);
public:
T value;
RAII(T (*constructor)(), void (*destructor)(T)) :
constructor(constructor),
destructor(destructor) {
value = constructor();
}
~RAII() {
destructor(value);
}
};
and to be used like this (using OpenGL's GLUquadric as an example):
RAII<GLUquadric*> quad = RAII<GLUquadric*>(gluNewQuadric, gluDeleteQuadric);
gluSphere(quad.value, 3, 20, 20)
Here's yet another C++11 RAII helper: https://github.com/ArtemGr/libglim/blob/master/raii.hpp
It runs a C++ functor at destruction:
auto unmap = raiiFun ([&]() {munmap (fd, size);});