Variable Assignment Tool

Hello,

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.)

Here's my current attempt:
LoadVariables.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#ifndef LOADVARIABLES_H
#define	LOADVARIABLES_H

#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <string>
#include <fstream>
#include <vector>
#include <map>
#include <string>

class LoadVariables {
public:
    LoadVariables();
    virtual ~LoadVariables();
    
    
    template<class T> void AddVariable(T &obj,const char &key);
    int ReadVariables(std::string filename);
    
private:
    struct VarStruct{
        void* address;
        std::string ID;
    };
    
    std::map<std::string,VarStruct> VarMap;

};

#endif	/* LOADVARIABLES_H */ 


LoadVariables.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include <typeinfo>

#include "LoadVariables.h"

using namespace std;

LoadVariables::LoadVariables() {
}

LoadVariables::~LoadVariables() {
}

template<class T>
void LoadVariables::AddVariable(T& obj, const char &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;            
        }
        else if(var.ID==typeid(unsigned int).name()){
            unsigned int *ptr=(unsigned int*)var.address;
            opts>>*ptr;            
        }
        else if(var.ID==typeid(bool).name()){
            bool *ptr=(bool*)var.address;
            opts>>*ptr;            
        }
        else if(var.ID==typeid(float).name()){
            float *ptr=(float*)var.address;
            opts>>*ptr;            
        }
        else if(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)

Any help/advice would be greatly appreciated.

Thanks,
Stephen
To fix the compiler error, change AddVariable() function definition to this:
template<class T> void AddVariable(T &obj,const char *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;    
is the same as
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
        if(var.ID==typeid(int).name()){
            int *ptr=(int*)var.address;
            opts>>*ptr;            
        }
        else if(var.ID==typeid(unsigned int).name()){
            unsigned int *ptr=(unsigned int*)var.address;
            opts>>*ptr;            
        }
        else if(var.ID==typeid(bool).name()){
            bool *ptr=(bool*)var.address;
            opts>>*ptr;            
        }
        else if(var.ID==typeid(float).name()){
            float *ptr=(float*)var.address;
            opts>>*ptr;            
        }
        else if(var.ID==typeid(double).name()){
            double *ptr=(double*)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.

Thanks,
Stephen
Topic archived. No new replies allowed.