I am attempting to write a C wrapper for some C++ data structures. Right now I've got the following in foo.cpp
typedef std::map<unsigned int, void *> _Map;
extern "C"{
void* map_create()
{
return reinterpret_cast<void*> (new _Map);
}
void map_put(void *map, unsigned int k, void *v)
{
Map *m = reinterpret_cast<_Map *> (map);
m->insert(std::pair<unsigned int, void *>(k, v));
}
}
In foo.h I've got
#ifdef __cplusplus
#define EXTERNC extern "C"
#else
#define EXTERNC
#endif
typedef void *Map;
EXTERNC void *map_create();
EXTERNC void map_put(void* map, unsigned int k, int v);
I include foo.h and I'm good to go.
Now, I wanted to iterate over a map and noticed C++ does that through iterators. I have no experience with C++ and don't know how iterators are implemented.
Can I iterate over a std::map using a C wrapper? How would these functions definitions look like and how would I use them in a for-loop in my C code?
You won't be able to use iterators directly. You can, of course, do something along the lines of creating/releasing objects and obtain the values somehow. It isn't going to be efficient, though. It would look something like this:
typedef std::map<unsigned int, void*> map_type;
typedef map_type::iterator map_iterator;
void* map_iterator_create(void* map) {
return new map_iterator(map.begin());
}
void map_iterator_destroy(void* it) {
delete static_cast<map_iterator*>(it);
}
int map_iterator_next(void* map, void* it, unsigned int* key, void** value) {
map_iterator* mit = static_cast<map_iterator*>(it);
if (static_cast<map_type*>(map)->end() == *mit) {
return 0; // no more elements
}
*key = mit->first;
*value = mit->second;
++mit;
return 1;
}
This particular approach does reduce the flexibility coming with iterators a bit (e.g., it doesn't support subranges) but these could be supported at different costs. You'd use this iterator approach like this:
void* it = map_iterator_create(map);
unsigned int key;
void* value;
while (map_iterator_next(map, it, &key, &value)) {
printf("key=%d value=%p\n", key, value);
}
map_iterator_destory(it);
It is probably more reasonable to not expose the iterator interface but rather an interface iterating over the sequence, e.g.:
extern "C" { typedef void (*map_function)(unsigned int, void*, void*); }
void map_iterate(void* map, map_function fun, void* userdata) {
map_type* m = static_cast<map_type*>(m);
std::for_each(m->begin(), m->end(),
[=](map_type::value_type const& v) {
fun(v.first, v.second, userdata);
});
}
... which would be used as
void my_iterating_fun(unsigned int key, void* value, void* userdata) {
printf("key=%d value=%p\n", key, value);
}
// ...
map_iterator(map, my_iterating_fun, 0);
I haven't tried to compile the code (i.e., it is probably riddled with small typos) but something along those lines should work.
Here's something that won't compile, but gives you an idea on how I'd do it
class MyIterator {
public:
MyIterator(Map map) {
it = map.begin();
}
void advance() {
++it;
}
bool isValid() {
return it != map.end();
}
private:
Map::const_iterator it;
const Map map;
};
extern "C" {
void* newIterator(void* map) {
return new MyIterator(static_cast<Map>(map));
}
void freeIterator(void* it) {
delete static_cast<Map>(map);
}
void advanceIterator(void* it) {
static_cast<MyIterator>(it)->advance();
}
void isValid(void* it) {
static_cast<MyIterator>(it)->isValid();
}
int getKey(void* iterator) {...}
void* getValue(void* iterator) {...}
}
Related
I'm writing a C backend for a C++ library and I want the C code to be able to iterate over the individual items of a forward iterator. In C++ the code which iterates over the items looks like this:
auto rng = wks.range(XLCellReference("A1"), XLCellReference("Q1"));
for (auto& cell : rng) {
// do something with "cell"
}
Now I want to export this code so that it is accessible from C. I'd like to be able to iterate over the items from C using a set of functions like this:
void *startiteration(void *cpp_obj);
void *getnextitem(void *cpp_obj, void *iter);
void finishiteration(void *cpp_obj, void *iter);
I'd imagine startiteration() to return an iterator pointer to the C code which would then be passed along with the C++ object pointer for all successive calls to getnextitem() and finishiteration().
But the problem here is that I can easily pass pointers of objects created in C++ using new between C and C++ code but I don't see how I could do the same with iterators since the iterators are returned by a class method and I don't think there's any way to turn the iterator into a pointer that I could pass to C code which would then pass it back to C++ during the iteration. Also, I don't know how I would "free" such an iterator.
Does anybody have some tips how I can iterate over a C++ forward iterator from C code? How should this be implemented?
EDIT
Implementation based on Silvio's suggestions:
struct myiter
{
XLCellIterator begin;
XLCellIterator end;
};
void *xlsx_startiteration(void *handle, int idx)
{
XLDocument *doc = (XLDocument *) handle;
XLWorkbook wb = doc->workbook();
auto wks = wb.worksheet(wb.sheetNames()[idx-1]);
XLCellRange cr = wks.range(XLCellReference("A1"), XLCellReference("Q1"));
myiter *it = new myiter();
it->begin = std::begin(static_cast<XLCellRange*>(cr));
it->end = std::end(static_cast<XLCellRange*>(cr));
return it;
}
auto rng = wks.range(XLCellReference("A1"), XLCellReference("Q1"));
for (auto& cell : rng) {
// do something with "cell"
}
I like doing 1:1 relationship between C++ and C. The following code outputs 3 lines var=1 var=2 var=3.
By wrapping the objects inside structures, the C side only forward declarations of structures and pointers. The C++ side sees all the rest. Additionally, C side will get a warning when passing invalid pointer to the wrong function.
#include <cstdio>
#include <vector>
typedef int do_not_know_what_is_the_type;
typedef std::vector<do_not_know_what_is_the_type> XLCellRange;
typedef XLCellRange::iterator XLCellIterator;
// header file
// C side
#ifdef __cplusplus
extern "C" {
#endif
struct wks_range_it_s;
void wks_range_it_inc(struct wks_range_it_s *);
bool wks_range_it_ne(struct wks_range_it_s *, struct wks_range_it_s *);
do_not_know_what_is_the_type wks_range_it_deref(struct wks_range_it_s *);
void wks_range_it_destruct(struct wks_range_it_s *);
struct wks_range_s;
struct wks_range_s *wks_range_construct();
void wks_range_destruct(struct wks_range_s *);
struct wks_range_it_s *wks_range_begin(struct wks_range_s *);
struct wks_range_it_s *wks_range_end(struct wks_range_s *);
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
// C++ side
struct wks_range_s {
XLCellRange rng;
};
struct wks_range_it_s {
XLCellIterator it;
};
extern "C"
void wks_range_it_inc(struct wks_range_it_s *t) {
++t->it;
}
extern "C"
bool wks_range_it_ne(struct wks_range_it_s *a, struct wks_range_it_s *b) {
return a->it != b->it;
}
extern "C"
do_not_know_what_is_the_type wks_range_it_deref(struct wks_range_it_s *t) {
return *t->it;
}
extern "C"
void wks_range_it_destruct(struct wks_range_it_s *t) {
delete t;
}
extern "C"
struct wks_range_s *wks_range_construct() {
// return new struct wks_range_s(wks.range(XLCellReference("A1"), XLCellReference("Q1")));
return new wks_range_s{{1,2,3}};
}
extern "C"
void wks_range_destruct(struct wks_range_s *t) {
delete t;
}
extern "C"
struct wks_range_it_s *wks_range_begin(struct wks_range_s *t) {
return new wks_range_it_s{t->rng.begin()};
}
extern "C"
struct wks_range_it_s *wks_range_end(struct wks_range_s *t) {
return new wks_range_it_s{t->rng.end()};
}
#endif
int main() {
// C code example
struct wks_range_s *rng = wks_range_construct();
// Almost 1:1 relationship with C++ range loop.
for(struct wks_range_it_s *begin = wks_range_begin(rng),
*end = wks_range_end(rng);
wks_range_it_ne(begin, end) ? 1 : (
// Yes, I'm sneaky.
wks_range_it_destruct(begin),
wks_range_it_destruct(end),
0);
wks_range_it_inc(begin)
) {
do_not_know_what_is_the_type var = wks_range_it_deref(begin);
// do something with var here?
printf("var=%d\n", var);
}
wks_range_destruct(rng);
}
Forward iterators in C++ are regular, which means they can be copied. In fact, in our case, we would only need to move them. Specifically, assuming the type of the iterator in question is I, then startiteration could do something like this.
struct Range {
I begin;
I end;
};
void* startiteration(void* cpp_obj) {
Range* my_range = new Range();
my_range->begin = std::begin(*static_cast<MyCppType*>(cpp_object));
my_range->end = std::end(*static_cast<MyCppType*>(cpp_object));
return my_range;
}
Just because the forward iterator is originally returned by value doesn't prohibit us from putting it into a pointer, either directly or indirectly. In our case, we grab both the beginning and the end and store them in a (heap-allocated) structure. Then finishiteration, of course, would be responsible for deleteing the constructed range object.
I am currently developing a library in C++ (Mainly because dependent libraries have C++ interfaces). I created a proof-of-concept implementation with C++ interfaces for quick development. The library has to mandatorily provide C interface for it. The C++ interface is good to have but can be modified/removed if it gets in the way of the C interface.
The C++ API right now looks something like this:
typedef struct {
// only basic C data types like int,float.
int a;
float b;
} Object;
typedef struct {
std::vector<Object> objects;
} GroupOfObjects;
typedef struct {
std::vector<GroupOfObjects> groups;
} Result;
typedef struct {
// some basic C data types
int init1;
int init2;
float init3;
// some C++ types which I can possibly replace with something compatible with C
std::string init4;
std::vector<std::string> init5;
} MyClassInitParams;
struct IMyClass {
public:
virtual bool initialize(MyClassInitParams ¶ms) = 0;
virtual bool getResult(Result &result) = 0;
//Other public methods, constructor, virtual destructor
}
// Actual implementation of the above interface
class MyClass : IMyClass {
}
IMyClass *createMyClassInstance();
I have come up with this C interface till now:
extern "C" {
typedef struct MyClass *MyClassHandle;
// A C version of the above MyClassInitParams
typedef struct{
} MyClassInitParams_C;
typedef struct {
Object * objects;
int numObjects;
} GroupOfObjects_C;
// A C version of the above Result structure
typedef struct{
GroupOfObjects_C *groups;
int numGroups;
}Result_C;
MyClassHandle MyClass_Create();
MyClass_Destroy(MyClassHandle handle);
int MyClass_Initialize(MyClassHandle handle, MyClassInitParams_C *params);
int MyClass_GetResult(MyClassHandle handle , Result_C *result);
void MyClass_FreeResult(Result_C *result);
} // end of extern "C"
Implementation of the C interface:
MyClassHandle MyClass_Create()
{
return createMyClassInstance();
}
MyClass_Destroy(MyClassHandle handle)
{
delete handle;
}
int MyClass_Initialize(MyClassHandle handle, MyClassInitParams_C *params)
{
MyClassInitParam params_cpp;
// fill params_cpp using the params structure
return handle->initialize (params_cpp);
}
int MyClass_GetResult(MyClassHandle handle , Result_C *result)
{
Result result_cpp;
bool ret = handle->getResult(result_cpp);
if (!ret)
return 0;
// Fill the C structure using the cpp structure
result->numGroups = result_cpp.groups.size();
result->groups = new GroupOfObjects_C[result->numGroups];
for (int i = 0; i < result->numGroups; i++) {
result->groups[i].numObjects = result_cpp.groups[i].objects.size();
result->groups[i].objects = new Object[result->groups[i].numObjects];
for (int j = 0; j < result->groups[i].numObjects; j++) {
result->groups[i].objects[j] = result_cpp.groups[i].objects[j];
}
}
return 1;
}
void MyClass_FreeResult(Result_C *result) {
// free all the arrays allocated in the above function
}
I have a few questions regarding this:
The GetResult method has a overhead of copying the objects from C++ vectors to the C arrays. Is there a more elegant and efficient way to handle this?
I will have to maintain the structures for both C and C++. Should I just use the C versions of the MyClassInitParams and Result structures in C++ interface? This will also help with (1).
If I use the solution in (2), does it make sense to even have the C++ interface? Or are there any advantages of keeping both the C and C++ interfaces in this case?
I'd suggest to return Result* from C MyClass_GetResult method, like int MyClass_GetResult(MyClassHandle handle, Result_C **result) or Result_C* MyClass_GetResult(MyClassHandle handle). Then, add accessors for groups and objects.
It's up to you to decide, but I'd rather to use one or the other, but not both.
First of all, I'd suggest to decide what language and its features (C or C++) you're going to use in order to implement your business logic. Next, another language becomes nothing more than a wrapper over logic implemented in another language. Again, if you use functions for accessing actual underlying data you'll get rid of copying this data, as you did in MyClass_GetResult method.
Here's an example
struct Object {
int a;
float b;
};
struct GroupOfObjects;
struct Result;
struct MyClass;
#ifdef __cplusplus
#include <vector>
struct GroupOfObjects {
std::vector<Object> objects;
};
struct Result {
std::vector<GroupOfObjects> groups;
};
struct MyClass {
private:
public:
Result getResult() { /*...*/ }
MyClass(int init1, int init2, float init3, const std::string& init4, const std::vector<std::string>& init5);
}
#endif
#ifdef __cplusplus
extern "C" {
#endif __cplusplus
struct Object* GroupOfObjects_GetObject(struct GroupOfObjects* g, size_t i)
/* { return &g.objects[i]; } */ // commented sections must be in cpp file, not in this header
size_t GroupOfObjects_GetCount(struct GroupOfObjects* g)
/* { return g.objects.size(); } */
struct GroupOfObjects* Result_GetGroup(struct Result* r, size_t i)
/* { return &r.groups[i]; } */
size_t Result_GetGroupCount(struct Result* r)
/* { return g.groups.size(); } */
MyClass *CreateMyClassInstance(int init1, int init2, float init3, const char* init4, const char** init5)
/* {
try {
std::vector<std::string> init5_v;
while (init5 != nullptr)
init5_v.push_back(std::string(*init5++));
return new MyClass(init1, init2, init3, std::string(init4), init5_v);
}
catch (...) {
return nullptr;
}
} */
void FreeMyClassInstance(struct MyClass* mc)
/* { delete mc; } */
Result* MyClass_GetResult(struct MyClass* mc)
/* {
Result *result = nullptr;
try {
result = new Result;
*result = mc->GetResult();
return result;
}
catch (...) {
delete result;
return nullptr;
}
} */
void FreeResult(struct Result* r)
/* { delete r; } */
#ifdef __cplusplus
} // end of extern "C"
#endif
I have a class named Handler wich stores some lambdas. What I want to do is to have a std::vector of std::function that stores all my events, for exemple. I really can't figure out why lambdas doesn't work as I expected.
Here's the handler.h:
class Handler
{
public:
Handler();
~Handler();
void Register(const char* outcome, std::function<auto()> lambda);
void Trigger(const char* outcome);
private:
std::vector<int> identifier;
std::vector<char*> outcome;
std::vector<std::function<auto()>> func;
};
And handler.cpp:
Handler::Handler()
{
//ctor stuff here
}
Handler::~Handler()
{
this->func.clear();
this->outcome.clear();
this->identifier.clear();
//...
}
void Handler::Register(const char* outcome, std::function<auto()> lambda)
{
static int identifier = 0;
identifier++;
this->outcome.push_back((char*)outcome);
this->identifier.push_back(identifier);
this->func.push_back(lambda);
//Sort outcome
}
void Handler::Trigger(const char * outcome)
{
int i;
for (i = 0; i < this->identifier.size(); i++)
{
if (!strcmp(outcome, this->outcome.at(i)))
break;
}
this->func[i]();
}
However, if I specify lambdas in a Handler::Register it wont let me throwing no suitable user-defined conversion from "lambda []void ()->void" to "std::function<auto()> exists. In this example I use void return type but other types also error, I don't understant why can't the template from std::function deduce it out, if it is what's happening.
Handler* events = new Handler();
events->Register("Up", [=]() -> void { //Error here!
//do stuff
//return something?
});
Is there any other way to do this, like without overloading Handler::Register?
auto is not a type, so std::function<auto()> is not a type either. From how you are using it, std::function<void()> is probably what you want.
There are other problems with your code, as noted in the comments, so I would change Handler to this
class Handler
{
public:
Handler();
// default ~Handler is fine
void Register(std::string outcome, std::function<void()> lambda);
void Trigger(const std::string & outcome outcome) const;
void Trigger(std::size_t index) const;
private:
using Outcomes = std::map<std::string, std::function<void()>/*, custom string comparator ?*/>;
std::vector<Outcomes::iterator> identifier;
Outcomes outcomes;
};
void Handler::Register(std::string outcome, std::function<void()> func)
{
auto emplaced = outcomes.emplace(std::move(outcome), std::move(func));
identifier.push_back(emplaced.first);
}
void Handler::Trigger(const std::string & outcome) const
{
outcomes.at(outcome)();
}
void Handler::Trigger(std::size_t index) const
{
identifier[index]->second();
}
For this project, I cannot use C++11, or add any additional dependencies (e.g. Boost).
What I'm trying to achieve is this:
typedef void (*processorFunction)(int numItems, std::string* items);
class Files
{
public:
Files() : m_KVSeparator('='), m_ListSeparator(',') {}
~Files() {}
void ReadDataFile(std::string filename, std::map<std::string, processorFunction> processorFunctions);
char m_KVSeparator;
char m_ListSeparator;
};
void Files::ReadDataFile(std::string filename, std::map<std::string, processorFunction> processorFunctions)
{
// The file parsing and choosing of the function omitted for brevity:
processorFunction processor = ...;
int numItems = ...;
std::string* items = ...;
processor(numItems, items);
}
// Example parser:
void time_limit_parser(int& timeLimit, int numItems, std::string* items)
{
timeLimit = atoi(items[0].c_str());
}
int main()
{
// Omitted getting the global file manager pointer
Files* files = ...;
std::map<std::string, processorFunction> configProcessorFunctions;
int timeLimit;
// ****** WHAT GOES HERE? ******
files->ReadDataFile("config.dat", configProcessorFunctions);
}
My question is what do I put on the ****** WHAT GOES HERE? ****** line? I would use std::bind to partially apply it (a la time_limit_parser(timeLimit)), but I can't use C++11 for this project.
You wouldn't be able to do what you wanted even with bind because bind doesn't return function pointers. Instead, you'd have to use the std::function template to wrap them.
As it turns out, there's nothing preventing you from doing exactly that yourself.
struct BaseProcessor
{
virtual void operator()(int numItems, std::string* items) = 0;
};
struct TimeLimitParser : public BaseProcessor
{
int& timeLimit;
TimeLimitParser(int& limit)
: timeLimit(limit)
{}
virtual void operator()(int numItems, std::string* items)
{
time_limit_parser(timeLimit, numItems, items);
}
};
int main()
{
// Omitted getting the global file manager pointer
Files* files = ...;
std::map<std::string, processorFunction*> configProcessorFunctions;
int timeLimit;
TimeLimitParser parser(timeLimit);
configProcessorFunctions["foo"] = &parser;
files->ReadDataFile("config.dat", configProcessorFunctions);
}
Obviously you need to change the definition of processFunction to match a pointer/reference to BaseProcessor, and it's clearly not quite as pretty as using bind or lambdas, but if you can't upgrade or get boost that's about as good at it'll get without some serious wizardry.
This is my code (simplification of a real-life problem):
class Foo {
public:
void f(const string& s) {
if (s == "lt") {
return lt();
} else if (s == "lte")
return lte();
} else if (s == "gt")
return gt();
} else if (s == "gte")
return gte();
}
}
void lt() { /* skipped */ }
void lte() { /* skipped */ }
void gt() { /* skipped */ }
void gte() { /* skipped */ }
};
This is how I would do it in PHP/Python/JavaScript/many other languages (example in PHP):
class Foo {
function f($s) {
return $this->$s();
}
function lt() { /* skipped */ }
function lte() { /* skipped */ }
function gt() { /* skipped */ }
function gte() { /* skipped */ }
}
How can I make my C++ code as elegant as this PHP example? Thanks in advance.
There is no reflection in C++. However, something like a std::map<std::string, void (Foo::*)()>should do the trick.
EDIT: Here is some ugly code to do it maintainably. Note the following :
This can probably be improved in various way
Please add code to deal with non-existent tokens. I did no error checking.
#define BEGIN_TOKEN_MAP \
template <int n> \
struct add_to_ \
{ \
static void act() {} \
}; \
std::map<std::string, void (Foo::*)()> map_;
#define DECLARE_TOKEN(str, n) \
template <> struct add_to_<n> \
{ \
static void act() { map_[#str] = &Foo::##str; add_to<n+1>::act();} \
};\
void str()
#define END_TOKEN_MAP \
void init_map() { add_to_<0>::act(); } \
void process_token(std::string s) { (this->*map_[s])(); }
class Foo
{
BEGIN_TOKEN_MAP
DECLARE_TOKEN(lt, 0) { ... }
DECLARE_TOKEN(gt, 1) { ... }
...
END_TOKEN_MAP
Foo() { init_map(); }
void f(const std::string& s) { process_token(s); }
};
You could use a dispatch table like:
typedef struct {
char *name;
void (*handler)();
} handler_t;
handler_t *handlers = {
{"lt", <},
{"lte", <e},
{"gt", >},
{"gte", >e},
(NULL, NULL}
};
void f(const string &s) {
for (int i=0; handlers[i].handler; ++i) {
if (0 == strcmp(s.c_str(), handlers[i].name)) {
handlers[i].handler();
return;
}
}
}
See also this SO question: How do you implement a dispatch table in your language of choice?
C++ is not dynamic, so there is no exact equivalent. A little more elegant would be to use a map and possibly function objects.
Following with the suggestion from Alexandre C., you can combine the std::map<... approach with an operator() to avoid having to call through to the void Foo::f.
For example:
class Foo {
private:
map<string,void (Foo::*)()> funs;
public:
// constructors etc.
void operator () (const string& s) {
if (funs.find (s) != funs.end ())
(this->*funs[s])();
}
// remainder
};
And you can now use foo similar to
Foo f;
f("lt"); // calls Foo::lt ()
f("lte"); // calls Foo::lte ();
// etc...
// Beware, brain-compiled code ahead!
namespace {
typedef std::map<std::string, void (Foo::*)()> operations_map_t;
typedef operations_map_t::value_type operations_entry_t;
const operations_entry_t* operations = { {"lt" , &Foo::lt }
, {"lte", &Foo::lte}
, {"gt" , &Foo::gt }
, {"gte", &Foo::gte} };
const operations_map_t operations_map( operations
, operations + sizeof(operations)
/ sizeof(operations[0]) );
}
void Foo::f(const string& s)
{
operations_map_t::const_iterator it = operations_map.find(s);
if(it == operations_map.end()) throw "Dooh!";
it->second();
}
I've upvoted Alexandre C, but I have reservations about building a data structure at run-time (populating the std::map) when the data is all known at compile-time.
I've upvoted the_void, but a linear search is only appropriate for relatively small data sets.
One option worth considering is a script (written in e.g. Python) to generate a hash-table or perfectly-balanced binary tree or whatever at build-time. You'll only do it if you have a recurring need to support large known-at-compile-time datasets, of course.
There's probably template-trickery ways to do this in C++ - they are Turing complete, and theres at least one compile-time parser state model generator, which is clearly more complex than a hash-table or binary tree. But personally, I wouldn't recommend it. A code-generating script will be simpler and more robust.
I have a script for generating ternary trees, but (1) it's a bit long for here, and (2) its not exactly a shining example of good coding.
You have several possibilities. But the first thing I should say is that C++ is strongly typed. Therefore a method that handles an instance of Foo on the one hand and Foo on the other hand is of a different type from of method that handles Foo and Bar.
Now, let's suppose that you only wish to handle Foo objects. Then you have 2 solutions:
function pointers
function objects
The function object is more general, notably, it would allow you to specify multiple combinations of parameters in one object.
class OperatorBase
{
public:
virtual ~OperatorBase() {}
bool operator()(Foo const& lhs, Foo const& rhs) const;
bool operator()(Foo const& lhs, Bar const& rhs) const;
bool operator()(Bar const& lhs, Foo const& rhs) const;
bool operator()(Bar const& lhs, Bar const& rhs) const;
private:
// virtual methods to actually implement this
};
struct LessThanOperator: OperatorBase
{
// impl
};
class OperatorFactory
{
public:
static OperatorBase& Get(std::string const& name);
template <class T>
static void Register(std::string const& name);
private:
typedef boost::ptr_map<std::string, OperatorBase> ops_t;
static ops_t& Get() { static ops_t O; return O; }
};
And then you can proceed:
// Choose the operator
OperatorBase& op = OperatorFactory::Get("lt");
Foo foo;
Bar bar;
bool const result = op(foo, bar);
It's quite tedious work though.
There are ways to do similar things in C++ with arrays and dynamic dispatch.
What you do is create an abstract class with some standard action(), like so:
class abstract_handler {
public:
virtual void action () = 0;
}
Then you create subclasses with different implementations of action(). For example, for your "ffa" branch you might write:
class ffa_handler : public abstract_handler {
public:
virtual action() {
// Do your custom "ffa" stuff in here
}
// Add your custom "ffa" members for action() to work on here.
// ...and of course a constructor to initialize them.
}
Then you create a map (in your case, indexed by std::string) of pointers to objects of each of your classes. At startup you populate this with the proper objects on the proper string indices. Then at runtime all you have to do is:
handler_map[index_string].action();