从基类指向成员的指针的类型

编程入门 行业动态 更新时间:2024-10-26 22:30:49
本文介绍了从基类指向成员的指针的类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我对成员指针有疑问.以下代码无法同时使用Oracle Solaris Studio 12.2的CC和cygwin GCC 4.3.4进行编译,但可与Microsoft Visual C ++ 2010一起使用:

I have a problem regarding member pointers. The following code fails to compile using both Oracle Solaris Studio 12.2's CC and cygwin GCC 4.3.4 but 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; }

在最后一行的下一行,上述两个编译器都找不到与Bar<B>::foo(int A::*)相匹配的内容.我编写了一个简单的测试,以确认表达式&B::x的类型实际上是int A::*:

At the next to last line both compilers mentioned above fail to find a match for Bar<B>::foo(int A::*). I wrote a simple test to confirm that the type of the expression &B::x is 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); // prints "A", even on MS VC++ 2010 return 0; }

以下变通办法适用于GCC(尚未在Oracle CC中进行测试),但由于含糊不清,在VC ++中失败:

The following workaround works with GCC (not tested with Oracle CC yet) but fails with VC++ 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)); } };

我的问题: 哪种行为是正确的?显然,VC ++从int A::*到int B::*进行了隐式上载以满足对成员函数模板的调用,其他两个编译器不应该考虑这样做吗?

My question: Which behavior is correct? Apparently VC++ does an implicit upcast from int A::* to int B::* to satisfy the call to the member function template, shouldn't the other two compilers consider doing the same?

推荐答案

允许从int A::*到int B::*的转换,这不是问题.问题在于模板参数推导,您可以看到是否尝试了以下程序,该程序为B::foo提供模板参数<int>并进行编译,以及一个非成员函数foo2产生与以前做过.

A conversion from int A::* to int B::* is allowed, and that's not the problem. The problem is in template argument deduction, as you can see if you try the following program which supplies a template argument <int> for B::foo and compiles, and a non-member function foo2 which produces the same error as B::foo did before.

struct A { int x; }; struct B : public A { }; template <typename T> class Bar { public: template<typename M> void foo(M T::*p); }; template<typename M> void foo2(M B::*p); int main(int, char*[]) { Bar<B> bbar; bbar.foo<int>(&B::x); foo2(&B::x); // error, but foo2<int>(&B::x) would work. return 0; }

我认为编译器应自行推断出模板参数<int>的情况并未涵盖这种情况. 14.8.2.1p3:

I think this situation is not covered by the cases where the compiler is supposed to deduce the template argument <int> on its own. 14.8.2.1p3:

通常,推论过程会尝试查找将使推论的A与A相同的模板参数值(在如上所述对类型A进行转换之后).但是,在三种情况下可能会有所不同:

In general, the deduction process attempts to find template argument values that will make the deduced A identical to A (after the type A is transformed as described above). However, there are three cases that allow a difference:

  • 如果原始P是引用类型,则推导的A(即引用所引用的类型)可以比A更具有cv限定性.
  • A可以是可以通过限定转换(conv.qual)转换为推导的A的另一种指针或指向成员类型的指针.
  • 如果P是一个类,并且P具有形式template-id,则A可以是推导的A的派生类.同样,如果P是指向形式template-id的类的指针,则A可以是指向由推导的A指向的派生类的指针.
  • 此处"P"是模板函数的参数类型:M B::*p,其中要确定模板类型参数M. "A"是实际参数的类型:int A::*. P和A当然不是引用或类,并且我们需要进行指针到成员转换的类型不是限定转换(仅描述const/volatile操作,例如X*到const X*或int X::*到const int X::*).

    Here "P" is the template function's argument type: M B::*p, where template type parameter M is to be determined. "A" is the type of the actual argument: int A::*. P and A are certainly not a reference or a class, and the sort of pointer-to-member conversion we would need for this to work is not a qualification conversion (which describes only const/volatile manipulations like X* to const X* or int X::* to const int X::*).

    因此无法推导出template参数,因此应在代码中添加<int>显式模板参数.

    So the template argument cannot be deduced, and you should add the <int> explicit template parameter to your code.

更多推荐

从基类指向成员的指针的类型

本文发布于:2023-07-28 02:45:41,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1226577.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:指针   成员   类型

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!