views:

111

answers:

5

when using either the '.', '->' or '->*' operators is there any way of getting the name of the function invoked (or the name of the variable in the case of '->*' and everything goes.

EDIT: Just to clarify I'm not talking about reflection but more something in the line of 'function' basically I want to create an overload of an operator (preferrably one of the three mentioned) which is aware of the right side of the operator

What I'm trying to accomplish is basically a compile time transformation of

obj->Function(a,b);

to

obj->Map("Function")(a,b); //Where Map(string) returns a function pointer

EDIT: Just to further clarify, The requirement is that the code will have to look like one of these three

obj.SomeMethod(args);
obj->SomeMethod(args);
obj->*SomeMethod(args);

any solution that fits that is acceptable as long as SomeMethod can be any valid identifier (I.e. any thing that can be used as a function name) and the solution will have to use SomeMethod as a lookup in a Map. The Map part is already implemented it's only the reinterpretation of what looks like a method call I seeking a solution to.

if that (as I'm affraid) can't be done then any solution with a new "operator" syntax will be accepted. Such as obj __ SomeMethod(args); as long as the lookup is based on the RHS of the "operator"

+1  A: 

C++ doesn't have any kind of reflection. The names of the functions are gone by the time that your executable is running. The only way to do it is to pass them in.

If you were planning to do something based on the method name, perhaps you just need virtual methods or overloading so that the right code is called.

Lou Franco
I'll need the name to lookup a value in a map and for my idea to work I basically need every name after the operator to compile so I can't use virtual methods since that would require me to define a set of acceptable names and I don't need to be able to do it runtime so I'm not looking for reflection
Rune FS
A: 

As far as I know, no. C++ does not support any form of reflection, so in order to get this kind of information you have to design your own tools and tricks.

Stefano Borini
ANd it's the designing the tools'n'tricks I'm stucked in and no I don't need reflection (which would be runtime) I'm happy to resolve it compile time
Rune FS
@Rune : I would try with a very very very very dangerous and complex use of macros, or a preprocessor that spots the call and replaces it with something smart. Qt moc does something similar, but I cannot recommend any solution. What you are doing is a little beyond the language and compiler's limits.
Stefano Borini
@Stefano you seem to have caught the Idea it's that very very very very dangerous and complex use of macros/preprocessor directives I'm trying to figure out and thanks for the warning which I'm _very_ aware of the risks
Rune FS
A: 

No. C++ has nearly no reflection. Unless you want this for debugging purposes you should not really need it. And debugging can be done even without it.

Answer to the EDIT: Either you use some kind of functor with several overloaded operator() functions or your map will have to contain only functions of same type, or at least of same parameters and return value (if you are willing to use something like boost::function<>). If you use functor with overloaded operator() then you are giving up compile time type safety and you will be limited to some N parameters.

What you have decided to do is akin to boost::bind/boost::function. Take a look at their headers. Unless you want to severally limit your implementation, it is unlikely you can end up with anything simpler than they use.

wilx
What do you know of my needs :) :) I do really need this to accomplish what I set out to do (which I must admit I doubt is doable) and no it's not for debugging
Rune FS
Thanks for the update after the edit. I have already implemented the functor part of it, that's the easy part. So currently I have the map I now need to be able to tak a line looking like obj->SomeFunction(params) and turn that into obj->Map["SomeFunction"](params). I habe not seen anything in boost that can solve that particular problem (the "rewritting" of the code part) feal free to correct me if I'm wrong since that would be the solution I'm looking for
Rune FS
I do not think that that is possible.
wilx
+1  A: 

when using either the '.', '->' or '->' operators is there any way of getting the name of the function invoked (or the name of the variable in the case of '->' and everything goes.

There is no built-in mechanism (i know of) that allows that.

You can get a name of current function during compile time, using __FUNCTION__ macro. It is not standard, but it is supported on MSVC, and may be supported on g++ (not sure).

If you want to know function name during runtime, then you'll have to implement some kind of special mechanism for that - build a table of function names and addresses (which will be initialized at startup) and search it for function name every time you need a function name from address. If compiler supports __FUNCTION__ macros or have any other means of getting name for current function, then you can simplify that by using macros (you can wrap entire "registration" procedure into single macro call that will be placed within function you want to register). This probably will be non-portable.

Program's debug information may also contain information you're looking for but it is even worse than relying on __FUNCTION__ macro.

SigTerm
Note that the `__func__` macro is part of C++0x and was already part of C99 : http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2340.htm
Tomaka17
+1  A: 

I have solved the problem you are facing just recently. I was doing Javascript bindings to C++ and needed to have a map of functions with name -> function. I am calling the functions like this:

vector<WebValue> params;  // Parameters for the function, I get these from the JS engine usually
params.push_back(asValue("Some string"));
params.push_back(asValue(123456));
params.push_back(asValue(1.0f));
functionMap["SomeFunction"]->call(params);  // SomeFunction must accept char*, int and float compatible parameters

and registering it like this:

functionMap["SomeFunction"] = jsExport(this, &MyClass::SomeFunction);

or like this if it's a member function and "this" is available in the current scope:

regMember(SomeFunction);

I used Boost Fusion and Boost Function Types to do the dirty job for me. It's available under the sources of OpenLieroX project:
http://bit.ly/dd70G6

The usage of it:
http://bit.ly/9Sa84q - contains methods for registering the functions to the map
http://bit.ly/b7oWNo - contains the handy regMember macro for registering member functions

You may want to look at other files in the directory as well for a better understanding:
http://bit.ly/b7oWNo

It is not exactly the way you described it in your question but hopefully it helps you.

dark_charlie
Funny, looks like the same basic idea as what i did for FireBreaths [`JSAPIAuto`](http://code.google.com/p/firebreath/wiki/classJSAPIAuto) :)
Georg Fritzsche
THanks for the answer unfortunately that's the part I'm already capable of doing. The goal is to not use a syntax like functionMap["SomeFunction"]->call(params); but a syntax that looks like calling a member function of an instance. To use the same example it would look like this obj->SomeFunction(params) where SomeFunction can be any name. (Pre)Compile time I'll have to translate that into what your call looks like and that transformation is what I'm asking for help about
Rune FS
Then you could make the base class have overloaded operator() for each number of parameters you have. These operators would simply make a parameter list like my vector of WebValues and invoke the function. This would of course give you a runtime overhead of converting the parameters twice but you cannot really avoid that as containers require a homogeneous type and pointer to functions/member functions have a different type per function.
dark_charlie
Still wouldn't solve the problem of getting the name. I do not have a method matching the RHS of the operator, I simply what to have the syntax look like there is a method with a given name without having that method. (The method will at runtime be represented by a functor but does not exist compile time)
Rune FS
Now I'm quite lost - if you create the functor objects at runtime, where do you take their name? If it is a function that should be called with this syntax, you can get its name by using macros and stringify: #define REGISTER(func) functionMap[#func] = makeFunction(func)
dark_charlie