Тип указателя на член из базового класса

У меня проблема с указателями участников. Следующий код не может быть скомпилирован с использованием 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::* чтобы удовлетворить вызов шаблона функции-члена, разве два других компилятора не должны делать то же самое?

Ответы на вопрос(1)

Ваш ответ на вопрос