我对成员指针有疑问。以下代码无法同时使用 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++ 做了一个隐式向上转换 from int A::*
toint B::*
来满足对成员函数模板的调用,其他两个编译器不应该考虑做同样的事情吗?