Is there a simple way to implement it in C++? - c++

I want to implement a function that can print out the value of one member variable (for example, 'aa') of struct ('Data') by it's name.
I try to use the macro definition as follows, but failed.
Is there a simple way to implement it?
#include <string>
#include <iostream>
using namespace std;
struct Data
{
int aa;
int bb;
int cc;
Data(): aa(1),bb(2),cc(3) {};
};
#define Param(a,b) a.##b
void Process(Data& data, const string& name)
{
cout << Param(data, name) << endl;
}
void main()
{
Data data;
Process(data, "aa");//I want print the value of Data.aa
Process(data, "bb");//I want print the value of Data.bb
Process(data, "cc");//I want print the value of Data.cc
}

This is not possible in C++.
This kind of usage is generally seen in scripting languages.
In C++ the variable names are constructed at compile time.

Your original code sample makes no sense to me because if you call Param(name) then the compiler has to know what instance of Data it has to use to determine the value of the member variable you want to get the value of (but I'm neither an expert using macros nor do I like them very much).
I tried to solve your problem using the following approach:
struct Data
{
int aa;
};
#define GetMemberValue(d, n) d.##n
int main()
{
Data d;
d.aa = 3;
int i = GetMemberValue(d, aa);
}
At least this approach returns the right result in this case.
Another thing is that you stated that you cannot call the member variables directly i.e. data.aa so you might run into the same issue using the macro. It's just a guess as I don't know the original code you're using.

Related

Can´t use an union element inside a nested structure as argument for scanf() to store desired value

I have a problem about to use scanf with an union element as an argument which superior union is part of a nested structure.
#include <stdio.h>
int main()
{
typedef union { float chair; int bed; } HABITATION;
typedef struct { HABITATION room; int number; } HOUSE;
scanf("%d",&HOUSE.room.bed);
}
The error message from the compiler is :
"Error: expected expression before ) >>ROOF<<".
What have i done wrong?
INFO:
I currently use C but i am also interested for the same operation and answer in/ for C++.
I dont know C, but in C++ your code should be equivalent to:
#include <stdio.h>
union HABITATION { float chair; int bed; };
struct HOUSE { HABITATION room; int number; };
int main()
{
scanf("%d",&HOUSE.room.bed);
}
Maybe now it is obvious that you merely defined two types, but you never create an instance of anything in this code. HOUSE is a type not an instance.
In c++ you would do
#include <iostream>
int main()
{
HOUSE h;
std::cin >> h.room.bed;
}
And probably not use all CAPITAL names. Some use them for globals, I am more on the side of banning them completely. Names should speak for themself, no need to shout. House is clear enough if you use first letter capital for classes and all small letters for instances (eg house). Thats also what Stroustrup suggests in his guideline.

I am trying to make a hashmap of of string functions

I am trying to make a map which stores a string as an identifier and a function that returns a string i have tried typedef but i kept running into problems because i couldn't convert my typedef string (command)() to a regular string i have also tried map commands but it gives me an expression expected error but it does work if i replace string with int. Does anybody know a way of doing this? This is what my code looks like
#include "iostream"
#include <map>
#include <functional>
using namespace std;
class GameController {
public:
void inputReader();
private:
bool gameOver = false;
map<string,string(*)()> commands;//Does not work
//commands
string commandReader(string* inputCommand);
void initCommands();
//both
char* end();
string run();
//while attacking
string attack();
string usePotion();
string useItem();
//while in room
string engage();
string searchRoom();
string rest();
string checkBag();
string checkMap();
string checkStats();
//string save();
};
#endif //ROGUE_GAMECONTROLLER_H
#include "GameController.h"
GameController::GameController(){
initCommands();
}
void GameController::inputReader() {
while (!gameOver){
string x;
getline(cin,x);
cout << commandReader(&x) << endl;
}
}
string GameController::commandReader(string *inputCommand) {
for (map<string,string>::iterator it = commands.begin(); it!=commands.end(); ++it)
{
if(it->first == *inputCommand)
{
return it->second;
}
}
return "Computer says no type help for commands";
}
void GameController::initCommands() {
commands["end"] = end;
//while attacking
commands["run"] = run;
commands["attack"] = attack;
commands["use potion"] = usePotion;
commands["use item"] = useItem;
//while in room
commands["engage"] = engage;//TODO
commands["search"] = searchRoom;
commands["rest"] = rest;
commands["check bag"] = checkBag;
commands["map"] = checkMap;
commands["stats"] = checkStats;
}
This question is tagged C++11, so here's a concise example which uses unordered_map (a real hash map, unlike std::map which my STL reference says is commonly implemented using binary search trees), and std::function.
#include <iostream>
#include <functional>
#include <string>
#include <unordered_map>
std::string foo()
{
return "foo!";
}
struct MyClass
{
static std::string bar()
{ return "bar!"; }
std::string FizzBuzz() const
{ return "FizzBuzz!"; }
std::string operator()() const
{ return "Myclass!"; }
};
int main(int argc, char **argv)
{
MyClass mc;
std::unordered_map<std::string, std::function<std::string()>> commands;
commands["myfoo"] = foo;
commands["mybar"] = MyClass::bar;
commands["myfb"] = std::bind(&MyClass::FizzBuzz, mc);
commands["myclass"] = mc;
for( const auto &f : commands)
std::cout << f.second() << std::endl;
std::cout << commands["myfoo"]() << std::endl;
return 0;
}
Pointers to member functions is not like pointers to free functions or even static methods. For one thing all member functions have a hidden this pointer in the function parameters that makes all of this object magic work.
Going through step by step:
First, define a helper:
typedef string (GameController::*funcp)();
This defines type funcp which represents a pointer to a member function of GameController (to partly take care of the this problem) that takes no parameters and returns string
Then, modify your map to use funcp
map<string, funcp> commands;
Then you have to change the assignment of the member functions a bit to be brutally explicit that it is a pointer and a member of GameController
commands["end"] = &GameController::end;
You can also save yourself some runtime trouble and use an initializer list here rather than a function and a map in every single GameController object. That'll take a bit of extra explaining and I have to be on the move in a few minutes. Sorry about that. A static map with static initializing really is better and worth your time researching, though.
The next bit I stole from the C++ Super FAQ. Read this link. Worth reading all of it, because it heads off a lot of the question you will have.
#define CALL_MEMBER_FN(object,ptrToMember) ((object).*(ptrToMember))
This makes calling the function awesomely easy.
return CALL_MEMBER_FN(*this, it->second)();
And that should about do it for you.
edit:
Tweej demonstrates the generally better way to do this, std::function and std::bind, in their answer. Since I'm advocating the ancient ways, I'd like to explain why.
Two reasons: one is tunnel vision directly answering OP's question.
The second is With the ancient ways I could easily make commands static and save having to create a new copy of commands for every instance of GameController. When using std::bind, you have to have the bound object, and that ruins the static idea.
Poking around at the idea of just using std::function seems to have born fruit and rendered obsolete the ancient ways. gone is the CALL_MEMBER_FN macro. Gone is the funcp typedef
The map is now defined as static, what I was aiming for the the old-pre C++11 approach. Note the funcp typedef is replaced by a function that takes a pointer to GameController to supply this.
static map<string, std::function<string(GameController*)>> commands;
And the map is now rigged to use a static initializer list. No function required. This initializer needs to sit outside the class definition because... I'm not sure why. I think this is changed in C++14.
map<string, std::function<string(GameController*)>> GameController::commands
{
{"end", &GameController::end},
{"run", &GameController::run},
{"attack", &GameController::attack},
{"use potion", &GameController::usePotion},
{"use item", &GameController::useItem},
{"engage", &GameController::engage},
{"search", &GameController::searchRoom},
{"rest", &GameController::rest},
{"check bag", &GameController::checkBag},
{"map", &GameController::checkMap},
{"stats", &GameController::checkStats}
};
The map is initialized once and only once. All GameControllers will use the same commands, so the constructor is really dumb
GameController::GameController()
{
// init function is gone
}
Command reader gets a big rip-up, mostly because the point of a map is you can search it by the key. So I search for the key rather than iterating. The function call is now obvious and dead simple:
string GameController::commandReader(const string &inputCommand)
{
map<string, std::function<string(GameController*)>>::iterator found = commands.find(inputCommand);
if (found != commands.end())
{
return found->second(this);
}
return "Computer says no type help for commands";
}

error: ‘length’ was not declared in this scope c++

I am beginner c++ programmer, It's my first program even (For those who are very keen to give negatives). I had written the same code in c but now trying to do in c++.
Where I get the following error.
error: ‘length’ was not declared in this scope
My code is as below.
#include <iostream>
#include <fstream>
#include <assert.h>
using namespace std;
class Huffman
{
public:
int data_size, length; //THis length variable is not accessible in main function below in main function.
Huffman(char *filename);
~Huffman();
struct Huffman1
{
int value;
unsigned char sym; /* symbol */
struct Huffman1 *left,*right; /* left and right subtrees */
}; typedef struct Huffman1 Node;
};
Huffman::Huffman(char * file_name)
{
//I will do something here soon
}
Huffman::~Huffman()
{
}
int main(int argc, char * * argv)
{
length=10; //Not accessible here.
if (argc < 2)
{
cout<<"Ohh.. Sorry , you forgot to provide the Input File please" <<endl;
return(0);
}
Huffman Object1(argv[1]);
return(0);
}
I am not sure that it's c++ programming error because it may be because i am compiling it g++ Filename.c -o filename. Could someone please correct if it's a programming error or it's due to the way i compile ?
thanks.
length is a member of the class, so it does not exist outside the class.
You can access lenth after creating an object of class Huffman as follows
Huffman Object(argv[1]);
Object.length = 10;
length belongs to Huffman class. So you should use it for Object1 after it's definition:
Huffman Object1(argv[1]);
Object1.length = 10;
You know, public: doesn't mean that anything put inside under that branch in the class tree, will be accessible everywhere it just means that you access the instance variables of the class through "dot notation" like so Object.length.
However if you truly wanted length to be accessible everywhere, you should declare it as a global variable:
short int length;
class Huffman{
...
};
...
It's a compile error and your code is responsible. You defined length inside your Huffman class. It's a member of that class, not a global variable.
Imagine your class as a C Struct. You'd need to create a struct first in order to access the variable. Same thing applies to C++ classes.
Try Object1.length = 10; after you create the instance of your class.
EDIT
For your purposes, use C++ classes as you would use C structs. That will do the trick.
I would actually put the Node struct declaration outside of the Huffman class. I think it's easier to understand. Also, using a typedef to a struct is not really that useful in C++ for these cases, the name of the struct is usable by just declaring the struct.
The pointers do not allocate memory for the struct themselves. Only after you allocate memory they will be usable, and even then they're members of Object1, so you need that too.
#include <iostream>
#include <fstream>
#include <assert.h>
using namespace std;
struct Node
{
int value;
unsigned char sym; /* symbol */
};
class Huffman
{
public:
int data_size, length; //THis length variable is not accessible in main function below in main function.
Huffman(char *filename);
~Huffman();
Node *left,*right; /* left and right subtrees */
};
Huffman::Huffman(char * file_name)
{
//I will do something here soon
}
Huffman::~Huffman()
{
}
int main(int argc, char * * argv)
{
length=10; //Not accessible here.
if (argc < 2)
{
cout<<"Ohh.. Sorry , you forgot to provide the Input File please" <<endl;
return(0);
}
Huffman Object1(argv[1]);
Object1.left = new Node;
Object1.right = new Node;
//Do your stuff here...
Object1.left->sym;
return(0);
}
This should get you started, it is by no means a perfect implementation. It's not even very C++ oriented, but I already went ahead of myself with the answer. This is a topic for a very different question, which you're welcome to ask in SO, but try not to make questions inside questions.
Good luck!
length is part of your class, not main, thus the compiler is right.
Members belong to an object and are accessed liek this:
Huffman huffmannObj(...);
std::cout << huffmannObj.length << std::endl;
length is a publicly accessible member of your class, but you'll need an instance of that class first before you can do anything with the member
Huffman h(whatever_constructor_params);
h.length = 10;
...is ok

How to adress variable by name stored in another variable (C++)

Good day,
I would like to reference a structure in a function by using a variable to store its name. Is this possible to do something like this in C++?
Definitely, all existing structures will be declared and initialised before any call is made (probably as global) and I will build in a check to make sure that only existing structures are referenced.
I would like something in this spirit:
struct StructName
{
...stuff
}a,b,c;
StructName a;
StructName b;
.
.
.
etc. including setting required values (in initialisation or elsewhere in code as needed)
and then I would have something like this to call from another portion of code:
void myFunction(char someInput)
{
some stuff
some stuff
externalFunction(static parameter, static parameter, _someInput_, static parameter);
yet some other stuff
}
where somInput is either a,b or c.
Please bear in mind I am a beginner with C, with little to no formal training in subject matter.
Thank you.
edit: If it was just myself, I would make do with case switch for someInput, referencing the structure directly in each case, but this part of a code is meant to be extendable by a non-programmer who would supply structures themselves, I would provide to him a template of structure initialisation code, and he would add the initialisation code to a specified place in the code, ammend the list of allowed names and compile the library.
You cannot convert a char or a char const * (runtime data) into a type (compile time information).
[edit] Well, actually you can with something like the following code, but since it uses templates, it will still be available only at the compile time, so you will not be able to pass function parameters, for example.
template < char C >
struct GetType;
template < >
struct GetType< 'a' > {
typedef struct { int foo; } type; };
template < >
struct GetType< 'b' > {
typedef struct { int bar; } type; };
GetType< 'a' >::type foo;
GetType< 'b' >::type bar;
Variable names disappear as part of the compilation step(s) in C and C++.
Typically, there are two scenarios that solve the type of problem you are describing:
User input corresponds to specific variable name.
You don't actually want the "name" of the variable, but just need a way to associate different data with different parts of your code.
In the second, simpler case, just use an array, and use the index to the element you want as the way to associate the correct data.
In the first case, you can use a std::map<std::string, structname&>. A std::map acts sort of like an array, but it is indexed by the first type give in the template parameters to std::map - so in this case, you can use std::string as an index.
Something like this:
#include <map>
#include <iostream>
#include <string>
struct StructName
{
int x;
};
std::map<std::string, StructName *> vars;
StructName a;
StructName b;
void registerVars()
{
vars["a"] = &a;
vars["b"] = &b;
}
int main()
{
std::string v;
registerVars();
while(std::cin >> v)
{
std::cin.ignore(1000, '\n');
if (vars.find(v) == vars.end())
{
std::cout << "No such variable" << std::endl;
}
else
{
vars[v]->x++;
std::cout << "variable " << v << " is " << vars[v]->x << std::endl;
}
}
return 0;
}

Static member function pointer to hold non static member function

This has defeated me. I want to have a static class variable which is a pointer to a (non-static) member function. I've tried all sorts of ways, but with no luck (including using typedefs, which just seemed to give me a different set of errors). In the code below I have the static class function pointer funcptr, and I can call it successfully from outside the class, but not from within the member function CallFuncptr - which is what I want to do. Any suggestions?
#include <stdio.h>
class A
{
public:
static int (A::*funcptr)();
int Four() { return 4;};
int CallFuncptr() { return (this->*funcptr)(); }
// doesn't link - undefined reference to `A::funcptr'
};
int (A::*funcptr)() = &A::Four;
int main()
{
A fred;
printf("four? %d\n", (fred.*funcptr)()); // This works
printf("four? %d\n", fred.CallFuncptr()); // But this is the way I want to call it
}
Try this instead:
#include <iostream>
class A {
public:
typedef int (A::*AMemFn)();
static AMemFn funcptr;
int Four() { return 4; }
int CallFuncptr() { return (this->*funcptr)(); }
};
A::AMemFn A::funcptr = &A::Four;
int main()
{
A fred;
std::cout << "four? " << fred.CallFuncptr() << std::endl;
}
jweyrich has a nice looking work around (and I suggest you use it), but I thought I'd elaborate on what the real problem in the code is:
Your problem is this line:
int (A::*funcptr)() = &A::Four;
This is defining a global variable called funcptr that is of the right type, rather than A::funcptr.
What you need is this mess:
int (A::*(A::funcptr))() = &A::Four;
This ugly mess is why I suggest you go down the typedef path to get a nice looking version like jweyrich's solution.
A static variable is not a member of a particular object -- it can only be accessed through the classes namespace. CallFuncptr should be rewritten:
int CallFuncptr() { return (*funcptr)();
which I think should work, since this function can access functions in A's namespace without specifying it.
Also, function pointers are more of a C construct than C++. You can access the static variable outside the class with the code:
A::CallFuncptr
since CallFunctptr just resides in A's namespace