C++ compiler cannot determine correct template function for arguments

I have the following code:

[code]

#include <cstdio>

struct true_type {

char type;

};

struct false_type {

int type;

};

struct has_foo_p {

template <typename T, void (T::*) (int) const = &T::foo> struct test {

typedef true_type is_true;

};

};

template<typename Pred>

struct test_c {

template<typename U>

static typename Pred::template test<U>::is_true f(U *);

template<typename U>

static false_type f(U const *);

};

template<typename Pred, typename T>

struct test {

static const bool value = sizeof(test_c<Pred>::template f<T>((T*)0).type) == 1;

};

template <typename T>

struct has_foo : test<has_foo_p,T>

{};

struct A {

void foo(int i) const {

std::printf("in A::foo, i = %d\n", i);

}

};

struct B {

};

template<typename T, bool>

struct maybe_call {

static void call(T const &o) {

o.foo(42);

}

};

template<typename T>

struct maybe_call<T, false> {

static void call(T const &o) {

}

};

template<typename T> void f(T const &o) {

maybe_call<T, has_foo><T>::value>::call(o);

}

int main() {

A a;

B b;

f(a);

f(b);

}

[/code]

Under gcc 4.1.1 and Intel C++ 9.1, it prints "in A::foo, i = 42" when run. Under Sun C++ 5.9 Linux build 27_2 and C++ 5.8 patch 121018-02 on Solaris, it prints nothing. The problem is that the compiler cannot specialise test_c::f<A>(A *), and uses test_c::f<A>(A const *) instead. The const version should only be used for f<B>.

Is this a compiler bug?

[1855 byte] By [rtarnell] at [2007-11-26 11:33:15]
# 1
Yes it'a bug in the compiler. Could you file this bug at http://bugs.sun.com?
Atanasyan at 2007-7-7 3:49:03 > top of Java-index,Development Tools,Solaris and Linux Development Tools...
# 2
thanks, i've reported that bug and also an assertion failure i came across while looking for a workaround.
rtarnell at 2007-7-7 3:49:03 > top of Java-index,Development Tools,Solaris and Linux Development Tools...