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?

