Тип указателя на член из базового класса
У меня проблема с указателями участников. Следующий код не может быть скомпилирован с использованием Oracle Solaris Studio 12.2 CC и Cygwin GCC 4.3.4, но работает с 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;
}
В следующей за последней строкой оба упомянутых выше компилятора не могут найти соответствие дляBar<B>::foo(int A::*)
, Я написал простой тест, чтобы подтвердить, что тип выражения&B::x
на самом деле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); // prints "A", even on MS VC++ 2010
return 0;
}
Следующий обходной путь работает с GCC (еще не протестирован с Oracle CC), но завершается неудачно с VC ++ из-за неоднозначности:
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));
}
};
Мой вопрос: какое поведение правильно? Видимо VC ++ делает неявный апскейт отint A::*
вint B::*
чтобы удовлетворить вызов шаблона функции-члена, разве два других компилятора не должны делать то же самое?