微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

关于使用auto进行成员函数指针类型推断的问题

如何解决关于使用auto进行成员函数指针类型推断的问题

我的问题是关于成员函数指针。这是一个示例代码: 类 Cfoo 继承 A,从 bar 继承 B。 我希望 &C::foo&C::bar 都属于同一类型 void (C::*)(), 但实际上它们是不同的类型,一种是void(A::*)()一个void(B::*)()。我使用 gdb ptype 命令来检查 数据类型。

我的问题是:这种行为是由 C++ 标准定义的吗?这个设计决定的基本原理是什么?

#include <type_traits>
#include <iostream>

struct A {
  void foo() {
    std::cout << this << std::endl;
  }
  int a;
};

struct B {
  void bar() {
    std::cout << this << std::endl;
  }
  int b;
};

struct C : public A,B { };

int main() {
  auto p1 = &C::foo;  // p1 is void (A::*)();
  auto p2 = &C::bar;  // p2 is void (B::*)();

  auto p3 = &A::foo;  // p3 is void (A::*)();

  bool b1 = std::is_same<decltype(p1),decltype(p2)>::value;
  bool b2 = std::is_same<decltype(p1),decltype(p3)>::value;
  std::cout << b1 << std::endl; // false
  std::cout << b2 << std::endl; // true
  return 0;
}

解决方法

是的,这是标准规定的:

当您有一个从其他类继承的类时,这些类的成员不是派生类的成员。它们仍然是它们的类的成员,并且派生类继承它们。因此,AB 的成员仍然是 AB 的成员,并且这仍然反映在它们的类型中(在适当的情况下)。这几乎是 C++ 的核心原则,您只是在实际中观察它。

就像你把一堆书放在书架上一样,这些书中的章节不会成为书架的一部分。它们仍然是书中的相同章节,您可以通过书架访问它们。

同样,您可以使用 C 访问其父类 AB 的成员,使用类 C 的名称。但它们仍然是 AB 的成员,这反映在它们的类型中。

当使用 use auto 时,您将获得表达式的确切类型。 C++ 允许您将指向基类成员的指针转换为指向派生类成员的指针。但是,这是一种转化。使用 auto 时不会发生转换,因为这正是 auto 的用途:使用表达式的实际类型,初始化/构造对象,并且不进行任何转换(有这里有一些细节,在参考文献方面增加了一些曲折,但这与本次讨论无关)。

,

这种选择背后的基本原理是,您对一种类型的假设越少,它就越好。

C 是一个 A,所以 (A::foo*)() 是继承自 A 的成员函数的最通用的类​​型。

为什么要强制执行更严格的类型?这是一个双赢的局面。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。