I'm trying to write some sort of command handler, which can tokenize an istringstream, automatically convert the tokens into variables of specific types and call a callback function with the converted variables as arguments. Here is simplified version of my code:
void Callback(int x, char y, float z) {
// do whatever
// note: For simplicity, I use a callback with a fixed signature
// here. In my actual implementation, the callback can be
// called with any number and types of arguments - but that
// I have solved already.
}
template<typename T>
T GetNextArgument(std::istringstream& strm) {
// get one token from the input stream and convert it to the required type
T val;
strm >> val;
return val;
}
template<typename ...Args>
void ParseAndExecute(std::istringstream& input_stream) {
Callback(GetNextArgument<Args>(input_stream)...);
}
int main() {
std::istringstream strm("15 a 17.3");
ParseAndExecute(strm);
return 0;
}
The problem I have is that the ParseAndExecute()
function after parameter pack expansion looks like this:
void ParseAndExecute(std::istringstream& strm) {
Callback(GetNextArgument<int>(strm),
GetNextArgument<char>(strm),
GetNextArgument<float>(strm));
}
Since the order of evaluation of the arguments is not defined, the tokens may be taken from the stream in incorrect order (and in my case, they always are). Instead I would need the expansion to give me something more like that:
void ParseAndExecute(std::istringstream& strm) {
int a1 = GetNextArgument<int>(strm);
char a2 = GetNextArgument<char>(strm);
float a3 = GetNextArgument<float>(strm);
Callback(a1, a2, a3);
}
But I cannot see how to achieve that with parameter pack expansion. Maybe with a recursive template...? Or do you have any other suggestion to achieve a similar functionality?
Aucun commentaire:
Enregistrer un commentaire