Reputation:
I'm trying to map a mapping between string
s and a custom struct, callable
. However, it's giving me "invalid declarator". I've tried a bunch of things, like typedef
ing it (e.g. typdef struct _c { } callable;
) but that just raises more errors.
I'm compiling with ideone.com, since I don't have a compiler at school but I still want to at least bang out decent code.
A minimum example (ideone link):
#include <vector>
#include <map>
#include <iostream>
#include <string>
using namespace std;
struct callable {
virtual void operator()(vector<string> args) = 0;
}
std::map<std::string, callable> commands =
{
{ "cmd", struct : callable
{
operator()(vector<string> args) {
out << "cmd called with args:" << endl;
for (auto i = args.begin(); args.end() != i; ++i) out << *i << endl;
}
}
}
}
int main() {
vector<string> args = {"hello", "world"};
commands["cd"](args);
}
And the error is:
prog.cpp:11:33: error: invalid declarator before 'commands'
std::map<std::string, callable> commands =
^
The expected output:
cmd called with args:
hello
world
As a side note, please provide an answer to this question before answering the more general question of mapping strings to code, unless this approach can't work.
Upvotes: 2
Views: 6077
Reputation: 62603
Syntax issues aside, your code smells Java. In C++ where functions are first-class citizens, you do not need to create callback classess for every possible callback. Instead, you simply pass function-like objects - either a pointer to function, or something wrapped inside std::function
. The former is simpler, the latter is more powerful. I suggest to work with simple pointers first. For instance, your code might be looking like following:
void do_cmd(const std::vector<std::string>& args);
typedef void (*cmd_func)(const std::vector<std::string>& cmd_args);
std::map<std::string, cmd_func> cmd_map = { {"cmd", &do_cmd} };
int main() {
(*cmd_map["cmd"])(args);
}
Upvotes: 3
Reputation: 334
I think you just lack a ';' after the closing brace of the struct declaration...
Upvotes: 1
Reputation: 5477
You forgot the extra semicolon after struct:
struct callable {
virtual void operator()(vector<string> args) = 0;
}; // <--- ; is needed.
This is what gives you the compiler error.
Upvotes: 12
Reputation: 1628
callable
is an abstract base class and can't be instantiated. Thus, you can't store an instance of one in a map
. You can store a pointer to a ABC in a map, but don't use a raw pointer use a smart one, such as below:
std::map<std::string, std::unique_ptr<callable> >
Upvotes: 2