#include <map>
#include <string>
#include <utility>
#include <iostream>
usingnamespace std;
class Parser
{
struct sub_parser_info_t // Filled in by register_sub_parser
{
string some_info;
bool (Parser::*sub_func)(const string& str); // Ptr to sub parser function
};
map<char, sub_parser_info_t> m_map; // Collection of sub parsers
public:
// Do the work
bool sub_parser_a(const string& str)
{ returntrue;
}
bool sub_parser_b(const string& str)
{ returntrue;
}
bool sub_parser_c(const string& str)
{ returntrue;
}
// Add a sub parser to the map
bool register_sub_parser(char ltr, bool (Parser::*parser)(const string& str))
{
sub_parser_info_t temp;
pair<map<char, sub_parser_info_t>::iterator, bool> rslt;
temp.sub_func = parser;
pair<char, sub_parser_info_t> pr(ltr, temp);
rslt = m_map.insert(pr);
if (!rslt.second)
returnfalse; // Failed to register switch
returntrue; // Added sub_parser
}
bool do_parse(const string& str)
{
pair<map<char, sub_parser_info_t>::iterator, bool> rslt;
map<char, sub_parser_info_t>::iterator iter;
bool (Parser:: * fp)(const string & str);
iter = m_map.find(str[0]);
if (iter == m_map.end())
returnfalse; // Handler not found
fp = iter->second.sub_func;
if (! fp(str)) // Do the sub parse
returnfalse; // sub_parser failed
returntrue; // sub parse successful
}
};
int main()
{
Parser parser;
const string str = "some text";
parser.register_sub_parser('a', &Parser::sub_parser_a);
parser.register_sub_parser('b', &Parser::sub_parser_b);
parser.register_sub_parser('c', &Parser::sub_parser_c);
parser.do_parse(str);
}
The problem is at line 53. The compiler doesn't like the function call.
Error C2171 '*': illegal on operands of type 'bool (__cdecl Parser::* )(const std::string &)' 53
Error C2064 term does not evaluate to a function taking 1 arguments 53
Line 53 should be: if (! (this->*fp)(str)) // Do the sub parse
You need a special operator ->* or .* to call a pointer to member. The arrow-star needs an pointer-to-object on its left side and a pointer-to-member on the right. The "extra" parentheses are required.