I have a problem with item pointers. The following code cannot compile using both Oracle Solaris Studio 12.2 CC and cygwin GCC 4.3.4, but it works with Microsoft Visual C ++ 2010:
struct A {
int x;
};
struct B : public A {
};
template<typename T> class Bar {
public:
template<typename M> void foo(M T::*p);
};
int main(int, char *[]) {
Bar<B> bbar;
bbar.foo(&B::x);
return 0;
}
In the closest to the last line, both compilers mentioned above cannot find a match for Bar<B>::foo(int A::*). I wrote a simple test to confirm that the type of expression &B::xis actually int A::*:
static void foo(int A::*p) {
std::cout << "A" << std::endl;
}
static void foo(int B::*p) {
std::cout << "B" << std::endl;
}
int main(int, char *[]) {
foo(&B::x);
return 0;
}
The following workaround works with GCC (not yet tested with Oracle CC), but with a VC ++ error due to ambiguity:
template<typename T> class Bar {
public:
template<typename M> void foo(M T::*p);
template<typename M, typename _T_base> inline void foo(M _T_base::*p) {
foo(static_cast<M T::*>(p));
}
};
My question is: Which behavior is correct? VC ++ seems to be doing an implicit raise from int A::*to int B::*to satisfy the member function template call, should the other two compilers not do the same?