pouët.net

c++ preprocessor question

category: code [glöplog]
hi

i have this macro:
Code:#define REGISTER_ELEMENT(className)\ Element * Allocate_##className(std::vector<std::string>::const_iterator &i, Bootstrap& b)\ {\ return new ##className(i,b);\ }\


and when I use it like: REGISTER_ELEMENT(Screen); I get the following error from the compiler (after preprocessing): error C3861: 'newScreen': identifier not found

Any idea on how to keep the spacing between "new" and "##className" ?

er, is this a trick question?

just drop the "##" in front of it ffs!
added on the 2012-04-26 08:00:33 by ryg ryg
as i read the documentation the hash signs do the following:

#foo => "foo" vs ##foo => foo
(one being a string literal and the other an identifier)
Nopes, ## is for concat the identifier with f.e. test -> #define TEST(foo) { some_routine(test##foo) } giving TEST(bla) { some_routine(testbla} while "some_routine(testfoo)" would result in some_routine(testfoo) giving a compile error :)
added on the 2012-04-26 08:17:39 by Danzig Danzig
You don't need the hash signs. E.g.:

#define VERY_BAD_WAY_TO_ADD(x, y) x+y

##: "The operator ## concatenates two arguments leaving no blank spaces between them:"
added on the 2012-04-26 08:17:48 by revival revival
btw. I would go for template here ;) avoid the macro...

template <class T> Element* Allocate<T>(std::vectory<std::string>::const_iterator &i, Bootstrap &b) { return new T(i.b); }

added on the 2012-04-26 08:19:40 by Danzig Danzig
doh, i'll delete the hash signs :-)
Quote:
std::vectory

I like that :) Apart from that, yes, throw away that macro, use the template variant unless you have a very very good reason to use macros (which you almost never have).
@Saga: ?thumb too big error :/ but leading to funny result :)

"Can't avoid Macro, try to avoid Macro if you can".. ok, the catch-version is better *G*
added on the 2012-04-26 11:39:45 by Danzig Danzig
Quote:
unless you have a very very good reason to use macros (which you almost never have).

Actually, I recently tried to write a compile time computation of an hash for constant strings using templates. The compiler NEVER ended up computing everything at compile time, it was simply unrolling the computation... In the end, I took the same code, removed the template and wrote a script in python to generate every possible version of the function for strings up to N characters. Only that way the compiler would compute the hash at compile time... It's not C++ preprocessor pre-processed but it is still pre-processed code and it might be possible to write it using macros.
So, no, C++ templates aren't the holy grail for everything.
But I agree that here, they do exactly the same and are prettier :)
added on the 2012-04-26 13:31:43 by MsK` MsK`
Also, sending in a non-const reference to a const_iterator could be seen as rather… odd. (In general, non-const references are pretty confusing beasts, iterators or no iterators.)
added on the 2012-04-26 14:50:33 by Sesse Sesse
Sesse, how is that related?
my goal with the macro is to define the factory functions compile time and registering them with a central factory.

The first part is easy-peasy to do using templates using something similar to what danzig posted.

The latter is a bit more tricky, in my mind, and the current solution is to let the macro generate a unique static variable to ensure the registration to take place at runtime.

Example of defintion:

Code: class Screen : public Element {... }; REGISTER_ELEMENT(Screen);


this unrolls to something similar to
Code: class Screen : public Element { ... }; Element * Allocate_Screen(std::vector<std::string>::const_iterator &i, Bootstrap& b) { ... } static bool isRegistered_Screen = RegisterElement("Screen", Allocate_Screen);

Probably not very helpful, but Google Test does something very similar. They also use macros. Maybe worth a look to see how they do it.
added on the 2012-04-26 21:12:45 by skrebbel skrebbel
Sesse, how is that related?
rasmus: Well, he did it in his sample code?
added on the 2012-04-27 01:10:05 by Sesse Sesse
Åh, Yes. I left one out in my original post. And sorry for double.post
@Sesse:
I dont get it...
1.) i was just "templating" the macro rasmus posted
2.) for gods sake WHAT DO I KNOW he wants with the const_iterator? maybe iterating the r/o vector in the constructor or whatever... a reference to a const_iterator does not have to be const... const would prevend rasmus from changing i -> for the sake of readable and intuitive code would result in std::string instead of const std::vector<std::string>::const_iterator as param :D
Or did I get you wrong?
added on the 2012-04-27 11:28:20 by Danzig Danzig
Danzig: Dude. It's not a personal attack. You guys posted one thing that was wrong/bad with his code. I'm pointing out another thing.
added on the 2012-04-27 14:16:19 by Sesse Sesse
@Sesse: I dont feel attacked at all :) I always forget that writting CAPS is like "shouting on the net". Im just curios WHAT (ups, I did it again...) you wanted to point out! Its not that I ever pass a const_iterator ref myself ;) but I still dont get your point.
added on the 2012-04-27 15:45:30 by Danzig Danzig
@Danzig: I simply wanted the original author to rethink if this was the best way to do whatever he/she wanted to do. For instance, sending lone iterators into a function is not necessarily wrong, but it's something I've rarely ever seen in solid, well-designed code, and it's hard to imagine exactly what would be accomplished by it that couldn't be done just by sending in either the vector itself or the first element. In short, it smells that there might be a better design of that particular function; nothing more, nothing less.
added on the 2012-04-27 17:39:34 by Sesse Sesse
Why would it be bad? I pass Them around all the time. The idea is that the called functions may read content and advance the iterator from an input stream/container
Ok, this is where elvis left the building :)
?too many discussions about good/bad c++
code error
Nearly EVERY day at work my new coders ask why
the legacy code from excoders is so bull.
Or older coders duplicate code with little changes
instead of using params in one funtion to decide some
differences for the sake of readability and you can not help it.
I am fed up with that,sorry.
Thanks for reading my personal meme :-)
added on the 2012-04-28 22:30:32 by Danzig Danzig
I love when statements arent backed

login