views:

113

answers:

3

How can I dump candidate functions (or viable functions or best viable functions) for a function invocation?

I know g++ provides an option to dump class hierarchy. (In fact, Visual Studio 2010 provides a similar option, but it's undocumented. I remember reading something about it—maybe in the VC++ team blog—but I can't remember it clearly.)

Recently, I have been reading about overload resolution in the C++0x draft, and it really embarrassed me.

Does any compiler provide an option to dump candidate functions, viable functions, or best viable functions?

Note: The candidate functions in overload resolution scenario is different from the candidate functions in the compiler error. The candidate/viable/best viable function in overload resolution scenario has their own meaning. I know their are three stages in overload resolution: find the candidate functions; find the viable functions; find the best viable functions. Normally, the best viable function is just one candidate; otherwise, the call is ambiguous. Each stage has their own rules.

+1  A: 

The easiest way to do this in Visual Studio is to compile an ambiguous call. The compiler will spit an error with a list of available candidates. Probably g++ will do the same.

ybungalobill
In this case, the available candidates dumped by the compiler error are the best viable functions. It's not the candidate functions or viable functions in the overload resolution.
kuangye
+3  A: 

I don't think there is any direct way.

One way is to deliberately create a conflict/ambiguity artificially. Most compilers emit an error of the form below, spewing out the list of considered candidates.

namespace A {
    void f(int x) {}
}
void f(int x) {}
void f(char x) {}

using namespace A;

int main(){
    f(2.2);
}

G++ error message:

prog.cpp: In function ‘int main()’:
prog.cpp:10: error: call of overloaded ‘f(double)’ is ambiguous 
prog.cpp:4: note: candidates are: void f(int)
prog.cpp:5: note:                 void f(char) 
prog.cpp:2: note:                 void A::f(int)
Chubsdad
The output candidate functions here is different from the candidate functions term in the overload resolution scenario..
kuangye
Why do you say that? A candidate is one which has the same name as the name of the function. Add another function 'int f(int x, char x){}' in the code I have shown above and observe how gcc reports that also as a candidate (even though it is not viable which is determined later)
Chubsdad
+1  A: 

One way to dump all the functions that have been considered, is to use a particular function name with a set of parameters that won't match anything:

struct DumpThemAll {};

int main(int argc, char* argv[])
{
  std::cout << DumpThemAll() << std::endl;
}

This will (normally) dump all operator<< that were considered for overload resolution. For this particular example, it can get hairy.

If you wish to dump only some specific functions, it's much more difficult. The only way to do that would be to artificially create an ambiguous call, however a call is ambiguous only if the spurious function you provide has the exact same "score" than the best match... so it's hard to devise one such function when you don't understand how this scoring work (and personally, I don't understand it all... there are just too many rules...)

However I would add that even though there are probably only a handful of persons who can cite the overload rules off the top of their head, or perhaps even make sense of it, in general it doesn't prevent you from working, for the standard tries to address every possible case while you only work with a couple of them.

Furthermore, abusing function / operator overload makes your program unreadable for it's arcane for humans (especially since subject to the particular of files included in the current translation unit).

Matthieu M.