I am looking for a way to print the name of the variable on which an instance's constructor is being invoked, from inside the constructor:
#include <iostream>
struct A {
A() {
std::cout << "variable name = " /*magic here*/ << "\n";
}
};
int main() {
A abc; // should output "variable name = abc"
A def; // should output "variable name = def"
}
Is this possible and how?
I don't think there's any way to do that without using macros.
If your class had a constructor taking a const char* then you could use a fake constructor macro to pass the variable name into the real constructor. I'm not sure why you'd want to do that though and this is a pretty ugly solution.
#define CONSTRUCT(type, name) type name(#name)
Related
I want to output the values of the private class members Bankcode and AgentName. How can I do this from within my main() function, or in general, outside of the BOURNE class.
My initial code attempts are below:
#include <iostream>
#include <string>
using namespace std;
class BOURNE
{
string Bankcode ={"THE SECRET CODE IS 00071712014"} ; /*private by default*/
string AgentName={"Jason Bourne"}; /*private by default*/
public:
void tryToGetSecretCodeandName(string theName ,string theCode); //trying to get the private
void trytoGetAgentName( string name); // try to get name
};
//***********************defining member function**************************************
void BOURNE::tryToGetSecretCodeandName(string theName, string theCode) //member defining function
{
Bankcode=theCode; //equalling name to the code here
AgentName=theName; //the samething here
cout<<theCode<<"\n"<<theName; //printing out the values
}
//************************main function*****************************
int main()
{
BOURNE justAnyObject; //making an object to the class
justAnyObject.tryToGetSecretCodeandName();
return 0;
}
Third Answer
Your code has two 'getter' style functions, but neither one takes no arguments. That is, both of your functions require arguments to be passed.
Your main function is calling get...CodeandName(), which has no arguments. As such, you get a compiler error, probably complaining about valid signatures, or arguments passed.
Edited Answer
If you only want to get the values, the typical (as far as I am aware) implementation is something like
std::string BOURNE::getCode()
{
return Bankcode;
}
std::string BOURNE::getName()
{
return AgentName;
}
int main()
{
BOURNE myAgent;
cout<< "The agent's name is : " << myAgent.getName() << endl;
cout<< "The agent's code is : " << myAgent.getCode() << endl;
}
Original Answer, left in because I feel like it's more useful
I suspect what you're asking is if you could do something like
void BOURNE::tryToGetSecretCodeandName(string theName, string theCode)
{
if (Bankcode == theCode) {
cout<< "You correctly guessed the code : " << Bankcode << endl;
}
if (AgentName == theName) {
cout << "You correctly guessed the agent's name : " << AgentName << endl;
}
}
This will allow you to repeatedly guess at the name, and get output when you're correct.
If you wanted to disable this kind of guessing, then you could consider creating a new class (possibly derived from/based on std::string - but see this question for reasons to be careful!) and implement an operator== function which always returned false.
Now, I am learning as to how to use structures properly in C++.
Is there another way to refer members in a structure.
As an example, below is my code.
I want to know if I can do something like test.b to refer name member in the structure.
Is there any incredible way to do so?
#include <iostream>
using namespace std;
struct A
{
string name = "Test";
};
int main()
{
A test;
string b = "name";
cout << test.name;
return 0;
}
If you don't need to use a string to reference the member then the way to do this is called "pointer to member":
struct A
{
int name;
int value;
};
main()
{
int A::* b = &A::name; // assign "name" to the variable called b
struct A test = {1,2}; // make a structure and fill it in
return test.*b; // use the variable called b to reference test.name
}
If you do need to refennce the items with a string the other way mentioned in the contents is to use a map. That can be useful if all your members are the same type.
#include <iostream>
#include <map>
main()
{
std::map<std::string,int> test; // make something that can be keyed by a string
test["name"]=1; // put something called "name" in the map with a value of 1
test["value"]=2; // put something called "value" in the map with a value of 2
std::cout << test["name"] << std::endl;
return 0;
}
What you are referring to is called Reflection (function/attribute access by name). C++ by default doesn't have reflection. So probably you need to look for libraries/frameworks for that. Google "C++ Reflection" for that. Boost is one of the solution out there for C++ reflection/serialization.
In C++ is it possible to declare a class which has a private std::string data member which is initialized with the stringized / stringified name of the instance symbol name? I can see that this couldn't work for temporaries, but for lvalues is it possible?
Here is what I would like:
#include <iostream>
#include <string>
class symbol {
public:
symbol() { // here goes some magical sauce }
void print() { std::cout << s_ << std::endl; }
private:
std::string s_;
};
int main() {
symbol bar, bah;
bar.print() // should print "bar" to STDOUT
bah.print() // should print "bah" to STDOUT
}
If I were to change the constructor to accept a string and introduce a preprocessor macro, then I can almost get what I want, but it smells bad.
#define makesymbol(x) foo x(#x)
symbol(const std::string & s) : s_(s) {}
// Now I can do:
makesymbol(test);
test.print(); // <--- This prints "test" followed by a newline to STDOUT
Basically what I would like to avoid is for the user to have to declare instances of symbols like:
symbol phi("phi");
Because it is annoying to read, annoying to type, and redundant. I can see why in some cases you might want a different string stored than the variable name, but I'm specifically trying to the solve the problem where you know you want the string to be equal to the stringized variable name.
I'd like to output some data to a file. For example assume I have two vectors of doubles:
vector<double> data1(10);
vector<double> data2(10);
is there an easy way to output this to a file so that the first row contains the headings 'data1' and 'data2' followed by the actual contents. The function which
outputs the data will be passed various different arrays so hardcoding the name
of the heading is not possible - ideally I'd like to convert the variable name
to some string and then output that string followed by the contents of the vector array. However, I'm not sure how to convert the variable name 'data1' to a string,
or indeed if it can easily be done (from reading the forums my guess is it can't)
If this is not possible an alternative might be to use an associative
container such as map or perhaps more simply a 'pair' container.
pair<vector<double>,string> data1(10,'data1');
Any suggestions would be welcome!
You can use the preprocessor "stringify" # to do what you want:
#include <stdio.h>
#define PRINTER(name) printer(#name, (name))
void printer(char *name, int value) {
printf("name: %s\tvalue: %d\n", name, value);
}
int main (int argc, char* argv[]) {
int foo = 0;
int bar = 1;
PRINTER(foo);
PRINTER(bar);
return 0;
}
name: foo value: 0
name: bar value: 1
(Sorry for printf, I never got the hang of <iostream>. But this should be enough.)
try this:
#define GET_VARIABLE_NAME(Variable) (#Variable)
//in functions
int var=0;
char* var_name= GET_VARIABLE_NAME(var);
I had the same problem. After a little bit of experimentation I created following macros that convert names of variables, fields, functions, methods and types to strings.
#define MACRO_VARIABLE_TO_STRING(Variable) (void(Variable),#Variable)
#define MACRO_FUNCTION_TO_STRING(Function) (void(&Function),#Function)
#define MACRO_METHOD_TO_STRING(ClassName,Method) (void(&ClassName::Method),#Method)
#define MACRO_TYPE_TO_STRING(Type) (void(sizeof(Type)),#Type)
The code uses comma operator and void conversion to force compiler to check if variable, function, etc. really exists. The nice thing is that it works well with uninitialized variables too. I tested it on both VC and GCC with all pedantic options I found out without any warning messages.
int GetAndPrintValue(const char* VariableName)
{
std::cout << VariableName << std::endl;
return 10;
}
int Variable=GetAndPrintValue(MACRO_VARIABLE_TO_STRING(Variable));
I use such code when I write parsers that reads data from input stream and if parsed variable is out of bounds it throws an exception with name of variable that failed my validity checks.
Slightly adapted from #sarnold's answer, for C++:
#define DEBUG(x) std::cout << #x << " = " << x << std::endl;
An example program which uses this:
int main() {
int foo = 1;
DEBUG(foo);
return 0;
}
You can use the preprocessor, there's a stringify token, but it's only available from the source, not to a function (you'd get the argument name).
I had a similar quest. In Qt, I got tired of constantly writing the variable name as a string without autocomplete when writing to qDebug().
After a lot of trial and error with different macros and functions, I found that this macro works great:
#define PRINT(x) ", " << #x << ": " << x
Example usage:
int someVariable = 42;
double anotherVariable = 13.37;
qDebug().nospace() << "Some text" << PRINT(someVariable) << PRINT(anotherVariable);
Output:
Some text, someVariable: 42, anotherVariable: 13.37
I guess this (or something very similar) will work for std::cout as well.
A bit late to the party, but I hope this can help anyone out there!
I'd have thought the obvious answer is to make the function that performs the output take the heading text as a string parameter.
For this case I have made nameof() macro. It returns a std::string name of a variable, type or member. It works like nameof() in C#.
For Example:
#include "nameof.h"
std::vector<double> data1(10);
std::string name = nameof(data1); // "data1"
struct Foo1
{
struct Foo2
{
Foo1* foo1;
};
Foo1* foo1;
Foo2 foo2;
};
name = nameof(Foo1::foo1->foo2.foo1); // "foo1"
name = nameof(123); // std::logic_error exception
I'm trying to initialize a private variable of my Class passing a const string &aString to it as parameter.
Here's my method:
void Image::initWithTextureFile(const std::string &inTextureName)
{
Texture2D *imTexture = TEXTURE_MANAGER->createTexture(inTextureName);
if(imTexture)
{
texture = imTexture;
scale = 1.0f;
name = inTextureName; //name is a private string variable inside my class
initImplementation();
}else {
printf("Could not load texture when creating Image from file %s\n",inTextureName.c_str());
}
}
My problem is the following, when I call this method I do it like:
myInitializer.initWithTextureFile("myFile.bmp");
When I'm inside the scope of initWithTextureFile the name variable takes the value of inTextureName. For this example if I cout << name << endl; inside initWithTextureFile i would get "myFile.bmp"
But when I leave the scope of the function, name looses it's value, so when i cout << name << endl; I get nothing printed in the console.
Could anyone point me out to what's going on here?
Name is declared:
private:
std::string name;
If you're outside the class scope, and cout << name compiles at all, it means you have another variable named name, and that's what's being picked up. If you want to refer to it outside the class, you'll have to come up with a way that will export it. You might, for example, have a member function like const std::string &GetName() { return name; }.
You either omitting something in your description or are not showing appropriate code that could help solve your problem.
This works:
#include <iostream>
#include <string>
using namespace std;
struct A
{
void f(const string& str) { name = str; }
void g() { cout << name << endl; }
string name;
};
int main()
{
A a;
a.f("test");
a.g();
}
Output:
test
That should work. Are you sure it is not being modified somewhere else, such as in initImplementation?
The problem probably have to do with the name variable : is it a pointer or ref to string instead of a plain string ?
The only reasonable explanation here is that you must be working with two different name objects. The one you declared as a class member should hold its value when you exit the method. It is just that outside the class method you must be printing a completely different name, which is empty.
I was going to say something about short-lived stack objects but I realised that was wrong. What it could be is something to do with exporting the containing class from a DLL.
If so, you might find a warning like this:
c:\yourclass.h(7): warning C4251: 'YourClass::name_' : class 'std::basic_string<_Elem,_Traits,_Ax>' needs to have dll-interface to be used by clients of class 'YourClass'
This thread describes more.
How is 'name' declared? It seems like maybe it's declared as a reference instead of an object.
Try:
name = std::string(inTextureName);