PDA

View Full Version : Help with possible array with function names



giblit
21st March 2013, 23:33
Is there an easier way to write this code by using like an array to store the names of functions?
for example something like this
QString functions [] = { "food()", "calorie" };
for(int i=0;i<2;i++){
output << entrynum->functions[i]
}
I tried doing something like this but doesn't work for me because of the ->

The code I have which works as I wish but doesn't look very neat unfortunately. =/

for(int i = 0; i < 9; i++){
string filename = "/";
string number;
stringstream convert;
convert << i;
number = convert.str();
filename.append(number);
filename.append(".txt");
string entrynum = "entry";
entrynum.append(number);

//cout << "The filename is: " << filename << endl;
QString filename2 = QString::fromStdString(filename);
QFile i(QDir::homePath() + filename2);
if (i.open(QIODevice::WriteOnly)) {
QTextStream output(&i);
output.setCodec("UTF-8");

for (int i = 0; i < treeWidget->topLevelItemCount(); ++i) {
ABItem *entrynum =
static_cast<ABItem *>(treeWidget->topLevelItem(i));
if(filename == "/0.txt"){
output << entrynum->food() << "\r\n" << endl;
output << endl;
} else if(filename == "/1.txt"){
output << entrynum->calorie() << "\r\n" << endl;
output << endl;
} else if(filename == "/2.txt"){
output << entrynum->protein() << "\r\n" << endl;
output << endl;
} else if(filename == "/3.txt"){
output << entrynum->carb() << "\r\n" << endl;
output << endl;
} else if(filename == "/4.txt"){
output << entrynum->carb() << "\r\n" << endl;
output << endl;
} else if(filename == "/5.txt"){
output << entrynum->fat() << "\r\n" << endl;
output << endl;
} else if(filename == "/6.txt"){
output << entrynum->sugar() << "\r\n" << endl;
output << endl;
} else if(filename == "/7.txt"){
output << entrynum->sodium() << "\r\n" << endl;
output << endl;
} else if(filename == "/8.txt"){
output << entrynum->fiber() << "\r\n" << endl;
output << endl;
}
}
}
}

d_stranz
22nd March 2013, 00:13
QString functions [] = { "food()", "calorie" };
for(int i=0;i<2;i++){
output << entrynum->functions[i]
}


What are you trying to achieve? It looks like what you want is a function dispatching mechanism, where you call a different function based on some key.

Use a std::map< QString, "pointer to member function" > or a QHash( QString, "pointer to member function" ), where the QString is the key (like "calorie", or "protein") and the value (i.e. the "pointer to member function" part) is a pointer to the function you want called for that keyword. If you don't know how to write the C++ code to declare a "pointer to member function", Google for that phrase. The 4th hit is a PDF that give a good review.

To create the lookup (dispatch) table:

std::map< QString, "pointer to member function" > functionMap;

functionMap[ QString( "food" ) ] = "pointer to Food::food()";
functionMap[ QString( "calorie" ) ] = "pointer to Food::calorie()";
functionMap[ QString( "protein" ) ] = "pointer to Food::protein()";

etc.

To use the dispatch table, you simply do this:

Food * myFood = new Food( "BigMac" );
QString key = "calorie";

output << myFood->(*functionMap[ key ])();

Of course, you can use anything for the key part - I've simply used the function names themselves for simplicity.

giblit
22nd March 2013, 00:50
Thx for reply but I'm a bit confused on the Mapping I might have to look up a few websites I tried a bunch of different things heres the last thing I tried:

map<QString,QString>functions;
functions["food"] = entrynum->food();
functions[0]
Heres what im trying to do.
say I have a QString called functions. I want it so I can do output << functions. Then in place of functions it would put "entrynum->food()". so basically a container or something to hold the names of my functions I will be calling so that way I can do something like functions[i] instead of entrynum->food, entrynum-> calories ect.

d_stranz
22nd March 2013, 04:31
I am confused about what you are trying to do. Are you trying to output the names of the functions in your class, or are you trying to output the values returned by those functions after you look up the function by name?

It would help if you would give an example of what you expect the output to look like (not the code to do it, the output text itself).

giblit
23rd March 2013, 00:00
I'm just trying to simplify

for (int i = 0; i < treeWidget->topLevelItemCount(); ++i) {
ABItem *entrynum =
static_cast<ABItem *>(treeWidget->topLevelItem(i));
if(filename == "/0.txt"){
output << entrynum->food() << "\r\n" << endl;
output << endl;
} else if(filename == "/1.txt"){
output << entrynum->calorie() << "\r\n" << endl;
output << endl;
} else if(filename == "/2.txt"){
output << entrynum->protein() << "\r\n" << endl;
output << endl;
} else if(filename == "/3.txt"){
output << entrynum->carb() << "\r\n" << endl;
output << endl;
} else if(filename == "/4.txt"){
output << entrynum->carb() << "\r\n" << endl;
output << endl;
} else if(filename == "/5.txt"){
output << entrynum->fat() << "\r\n" << endl;
output << endl;
} else if(filename == "/6.txt"){
output << entrynum->sugar() << "\r\n" << endl;
output << endl;
} else if(filename == "/7.txt"){
output << entrynum->sodium() << "\r\n" << endl;
output << endl;
} else if(filename == "/8.txt"){
output << entrynum->fiber() << "\r\n" << endl;
output << endl;
}
}
to something more like this:

for (int i = 0; i < treeWidget->topLevelItemCount(); ++i) {
ABItem *entrynum =
static_cast<ABItem *>(treeWidget->topLevelItem(i));
if(filename == filename){
output << entrynum->array[i] << "\r\n" << endl;
output << endl;
}
}

The orig. code works fine its just bulky and gross looking was trying to make it look nicer.

Added after 15 minutes:

PS: The outputs are 9 Text files which are named 0.txt, 1.txt, 2.txt ect... and they contain seperate data inside of each for example 0.txt has:
"Food1
Food2" inside of the file