It is not possible to make a version of operator ==
the way you want. It can't be made static. If it is a member, then it must take one argument.
If you are willing to "duplicate code", then you can play tricks with namespaces. Your generic interpreter could be a template that takes a language specific derived class as a template parameter. It in turn calls a templated operator==
based on a language specific token.
template <typename TOKEN>
bool operator == (const std::string &l, const TOKEN token) {
return token == l;
}
// Language specific interpreters inherit from this template
template <typename LANG>
class Interpreter {
public:
void interpret () {
std::string s("hi");
if (s == LANG::KEYWORD_ELSE) {}
}
};
Each language specific subclass of Interpreter
lies in a language specific namespace. The implementation repeats enumerations of the keywords, but otherwise defers to the template implementation.
namespace Lang0 {
class Interpreter : public ::Interpreter<Lang0::Interpreter> {
//...
public:
enum Token { KEYWORD_ELSE, //...
};
static Interpreter & instance () {
static Interpreter interpreter;
return interpreter;
}
};
}
namespace Lang1 {
class Interpreter : public ::Interpreter<Lang1::Interpreter> {
//...
public:
enum Token { KEYWORD_ELSE, //...
};
static Interpreter & instance () {
static Interpreter interpreter;
return interpreter;
}
};
}
Each namespace also provides a language specific implementation for operator==
to compare a string to the language specific token.
namespace Lang0 {
bool operator == (const Interpreter::Token token, const std::string &l) {
//...
}
}
namespace Lang1 {
bool operator == (const Interpreter::Token token, const std::string &l) {
//...
}
}
Then, when the template implementation of Interpreter
calls the template version of operator==
, it resolves to the language specific implementation in the respective language specific namespace.