Reputation: 1243
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.
Upvotes: 0
Views: 1433
Reputation: 138071
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.
Upvotes: 1