I'm trying to write a tool that can read text file and use the information to assign values to variables to I have a data analysis program I use for research. (I'm tired of needing to recompile for variable tweaks).
The problem I'm struggling with is how to register a variable of arbitrary type with my tool without overloading the AddVariable() method with every type. (I would also appreciate advice on avoiding the if, else if list in my ReadVariables() method if it's possible.)
#include <typeinfo>
#include "LoadVariables.h"
usingnamespace std;
LoadVariables::LoadVariables() {
}
LoadVariables::~LoadVariables() {
}
template<class T>
void LoadVariables::AddVariable(T& obj, constchar &key){
VarStruct var;
var.address=&obj;
var.ID=typeid(obj).name();
VarMap.insert(pair<string,VarStruct>(key,var));
}
int LoadVariables::ReadVariables(string filename){
ifstream opts;
opts.open(filename.c_str());
opts.seekg(0,ios::beg);
int counter=0;
while(opts.tellg()>=0){
string curr_line,key;
int lineStart=opts.tellg();
char line[500];
opts.getline(line,500);
curr_line=line;
if(curr_line.compare(0,2,"//")==0)continue;
opts.seekg(lineStart,ios::beg);
opts>>key;
VarStruct var;
try{var=VarMap.at(key);}
catch(...){
cerr<<"No no variable named "<<
key<<" exists!!! Line is ignored."<<endl;
opts.seekg(lineStart,ios::beg);
opts.getline(line,500);
++counter;
continue;
}
if(var.ID==typeid(int).name()){
int *ptr=(int*)var.address;
opts>>*ptr;
}
elseif(var.ID==typeid(unsignedint).name()){
unsignedint *ptr=(unsignedint*)var.address;
opts>>*ptr;
}
elseif(var.ID==typeid(bool).name()){
bool *ptr=(bool*)var.address;
opts>>*ptr;
}
elseif(var.ID==typeid(float).name()){
float *ptr=(float*)var.address;
opts>>*ptr;
}
elseif(var.ID==typeid(double).name()){
double *ptr=(double*)var.address;
opts>>*ptr;
}
else {
cerr<<"Unknown variable type passed!!!"<<
" Line will be ignored."<<endl;
opts.seekg(lineStart,ios::beg);
opts.getline(line,500);
++counter;
}
}
return counter;
}
As this is it will compile but when I try to register a variable with this tool in my analysis program I get a compiler error. I've tried calling it like this:
1 2 3
LoadVariables Lvar;
Lvar.AddVariable<int>(evt.eMask,"eMask");
int ReadErrors=Lvar.ReadVariables("Variables.txt");
and like this:
1 2 3
LoadVariables Lvar;
Lvar.AddVariable(evt.eMask,"eMask"); //evt.eMask is an int
int ReadErrors=Lvar.ReadVariables("Variables.txt");
The error is the same and says something like, "LoadVariables has no element AddVariable(int&,const char&)" (I'd copy paste the error but the power is out in the lab where I run my code)
To fix the compiler error, change AddVariable() function definition to this: template<class T> void AddVariable(T &obj,constchar *key) or template<class T> void AddVariable(T& obj, string key)
I think C++0x might help you:
1 2
auto *ptr=(decltype(var.ID)*)var.address;
opts>>*ptr;
I'm still getting the compiler error:
plotter.cc:1585: undefined reference to `void LoadVariables::AddVariable<double>(double&, char const*)' //or int, bool or whatever...
I'll have to ask the sys admin about updating our version of gcc (4.3 currently) before I can use auto or decltype.