Archived

This topic is now archived and is closed to further replies.

#DEFINE "magic"...

This topic is 4958 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Yes, yes, macros are evil, but they are also the lesser evil in this case. What I have is a derivitive creator that takes the name you want and generates the header that you need for it, which you then modify with a CPP. Now the problem is that I need to be able to take what is given to me straight from a define, and make it into a string. Now, I can see much confusion from that statement, so here''s what I want:
#define BLAH(name) cout << "name";
See what I mean? Let''s say I have a variable named foo which holds a string "bar". Now if I do BLAH(foo), I want it to print out foo, not bar. Is it possible? When I tried with the source I put above it printed out name, not foo and not bar (and I understand why, I mean, how''s the compiler supposed to know wether I want that "name" replaced or if it''s actually a part of the text?). So is there a way to tell it "Yes, I do want that name replaced."?

Share this post


Link to post
Share on other sites
Yes, it''s possible, using a # prefix:

#define BLAH(name) cout << #name

If the thing you want to convert to a string is the result of another macro you can use the BOOST_PP_STRINGIZE macro from the boost preprocessor library (boost.org)

Share this post


Link to post
Share on other sites
This is will print: foo = bar

#define VAR_DUMP( var ) cout << #var " = " << var << "\n"


edit: bah,... beaten by twanvl

You should never let your fears become the boundaries of your dreams.

[edited by - _DarkWIng_ on May 20, 2004 4:26:28 PM]

Share this post


Link to post
Share on other sites

#define blah(name) printf(#name);


As my knowledge of C++ console io I went fro printf.. But I guess it works with cout to..
[edit] - Slow connection... Got beaten not one..but twice.. Horrible...
"For every complex problem there is an answer that is clear, simple, and wrong." H L Mencken

[edited by - Rickmeister on May 20, 2004 4:27:25 PM]

Share this post


Link to post
Share on other sites
<joke>
#define MAGIC MORE_MAGIC
</joke>

Sorry...


“Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.”
— Brian W. Kernighan

Share this post


Link to post
Share on other sites
Ah, thanks for that. Out of curiosity, does that work with TCHAR or am I going to have to rely on the converter from ansi to unicode?

Edit:
twanvl said:
If the thing you want to convert to a string is the result of another macro you can use the BOOST_PP_STRINGIZE macro from the boost preprocessor library (boost.org)


So if I want to do, say #(name ## _Combined) or something like that I'm going to have to use boost?

[edited by - Erzengeldeslichtes on May 20, 2004 4:38:54 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by Erzengeldeslichtes
Ah, thanks for that. Out of curiosity, does that work with TCHAR or am I going to have to rely on the converter from ansi to unicode?


std::cout works with narrow characters (char). std::wcout works with wide characters (wchar_t).

Somewhat important note - wide characters != Unicode. Unicode is only one particular encoding, which does use wide characters. Which encoding is actually used by a stream is controlled by whatever locale the stream has been imbued with.

As for the stringizing operator, I do believe it only yields narrow strings. You'll have to prefix with an L by yourself.


“Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.”
— Brian W. Kernighan


[edited by - Fruny on May 20, 2004 4:41:51 PM]

Share this post


Link to post
Share on other sites
quote:

So if I want to do, say #(name ## _Combined) or something like that I''m going to have to use boost?


If you want to do it that way, probably yes (don''t know for sure) you might end up with "name ## _Combined" or probably a compile error. But you can do this in another way:
#name "_Combined"
In C(++) if you write "one string" "another string" they will be concatenated to form "one stringanother string"

Share this post


Link to post
Share on other sites
And now that I know about that, I can do "#define Blah(name, prefix) class prefix ## _SPECIAL_ ## name { public: char* Name() { return #prefix #name; } };", which is a simplified version of what I want, and now works! Thank you again!

Sure, preprocessor can work in strange ways, but I like it's capabilities... Just have to make sure it's used correctly.

[edited by - Erzengeldeslichtes on May 20, 2004 5:09:04 PM]

Share this post


Link to post
Share on other sites
I did say that was a simplified preproccessor call. The actual one I''m using is actually a pluggable factory creator. Since Pluggable factories are almost always the same and require only modification in name, return object, and the method of creating that object, I decided that making a macro that makes it easy to generate the class declaration was the best way to go, and then within the CPP I can do the modifications on how to create the object from a string.

Share this post


Link to post
Share on other sites
Hey, why not make a templated version of the factory?

like:


class IFactory {
virtual void* create(ID id);
};

//Creation policy

class ICreationMethod {
virtual void* create();
};

class SingletonCreation : public ICreationMethod {
void* create() {
//create as a singleton and manage as a singleton...

}
}

template <class TYPE, class CREATION_METHOD>
class FactoryItemCreation : public CREATION_METHOD<TYPEA>, public ICreationMethod {

};

template <class T>
class Factory : public IFactory {
void* create(ID id) {
return (getCreationMethod.create());
}

ICreationMethod* getCreationMethod(ID id) {
//find the creation method of id...

}

bool addType(ID id, ICreationMethod* pCreator){
//insert new entry...

}
};


Something like that, think its better than messing around with macros.

Share this post


Link to post
Share on other sites
Yes, I thought of making a template, but:

quote:
Original post by Erzengeldeslichtes
... and then within the CPP I can do the modifications on how to create the object from a string.


I'm not necessarilly able to modify the code to the objects I'm creating, so I can't add a string constructor, therefore I need to be able to take a string and convert it into what the constructor actually wants. As such I need derived classes that take the parameters, parse them into what the object it's designed to create needs, and then create the object with the needed parameters. That's what the macro is for, the derived classes.

[edited by - Erzengeldeslichtes on May 20, 2004 8:44:51 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by FxMazter
Hey, why not make a templated version of the factory?

like:
[snip]

Something like that, think its better than messing around with macros.
Yes, but compare the volume code you wrote for that to the 1 line macro you need...

Share this post


Link to post
Share on other sites
template<typename T> inline std::string nameOfClass() {
return typeid(T).name();
}


_should_ work the way you need for a factory..


class Factory {
template<typename T> register() {
register(nameOfClass<T>(),&T::create);
}
}


like that..

but some compilers (vc6 i know), don''t return "T" with typeid(T).name(), but "struct T" or "class T" or whatever else..

wich, in case you want to support vc6, you have to handle (or you have to

Obj* obj = Factory::create("class T");
instead of
Obj* obj = Factory::create("T");


hope that gives an idea.. else, yes.. the #name results in "name"..




If that''s not the help you''re after then you''re going to have to explain the problem better than what you have. - joanusdmentia

davepermen.net

Share this post


Link to post
Share on other sites