In C#, what I want would look something like this:
IDictionary<string, action()> dict = new Dictionary<string, action()>();
How do I do this in C++? This gives compiler errors:
map<string, void()> exercises;
In C#, what I want would look something like this:
IDictionary<string, action()> dict = new Dictionary<string, action()>();
How do I do this in C++? This gives compiler errors:
map<string, void()> exercises;
Try using a function object. For example, you can use boost::function.
In C++ function pointers need to be used. Using your C++ example, you could inline it as:
map<string, void(*)()> exercises;
But it may be more useful to the casual observer to do it in two lines:
typedef void (*pointer_to_void_function)();
map<string, pointer_to_void_function> exercises;
(Choose names to suit.)
Note, that it's probably even easier to casual observers to add another typedef...
typedef void (*pointer_to_void_function)();
typedef map<string, pointer_to_void_function> ExerciseMapping;
ExerciseMapping exercises;
Then, when you want to use iterators or whatever, you just type ExerciseMapping::iterator
instead of needing to type the map... stuff. (This also makes it easier to change your implementation later.)
Use boost::function, a polymorphous wrapper for any object that can be called with your signature (including functions, function objects etc).
map<string, function<void()>> ...;
Note that the new C++ standard has already included function
in <functional>
.
To explain the backgrounds: The only builtin mechanism of this kind in C++ are old C-style function pointers (void (*)()
). These are extremely low-level, basically just storing the memory address of a function, and therefore far from even coming close to the power of C#'s delegates.
You can't create anonymous functions, neither can you refer to a particular object's member functions or any variables or data (closures).
Thus, one often utilizes so called functors which are classes that mimic the behaviour of a function by overloading the operator ()
. In combination with templates, they are used whereever ordinary function pointers can be used.
The problem is that these functors often consist of peculiar or anonymous types that can't be referred to conveniently.
The function
is the coolest way to address them all - Everything that behaves like a function, including cool new lambda-style expressions.
function<void()> f = []() { cout << "Hello, World"> };
f();