Question

I'm trying to understand how to select the right overloaded function template at compile-time, but the compiler is giving me a hard time. I can make it work, but I don't understand what is going on. Let me explain.

I have two structs A and B like below. One has a special function and the other a normal.

struct A
{
    void special() { std::cout << "special called.\n"; }
};

struct B
{
    void normal() { std::cout << "normal called.\n"; }
};

My intension is to have a mechanism, which at compile-time selects the right overloaded function template depending on if the special function is available. I have two functions run, which take the struct as a parameter, so they can call the appropriate function.

template<class Func, Func f> struct Sfinae {};

template <typename U>
static void run(U& u, Sfinae<void (U::*)(), &U::special>* = 0)
{
    u.special();
}

template <typename U>
static void run(U& u, ...)
{
    u.normal();
}

I've tested this with the following, with various results:

int main()
{
    A a;
    run<A>(a, 0); // works
    run<A>(a); // ERROR: ambiguous overloaded function
    run(a, 0); // ERROR: A has no member normal
    run(a); // ERROR: ambiguous overloaded function

    B b;
    run<B>(b, 0); // works
    run<B>(b); // works
    run(b, 0); // works
    run(b); // works

    return 0;
}

I'd like to use it as run(a) without any extra argument or <>. Is there something wrong with my code when this is not working?

Also, I'm interested to understand what is going on here and why this is deducing things like this, so I need to give <A> for A but not for B? I don't know what the standard says and if this is different between compilers, but at least gcc4.4.4 on Linux and gcc 4.0.1 on Mac work like I've described.

Can someone please shed some light on this? Thanks!

No correct solution

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top