c++ - 关于使用auto进行成员函数指针类型推断的问题
问题描述
我的问题是关于成员函数指针。这里有一个示例代码:类C
继承foo
自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;
}
解决方案
是的,这是标准规定的:
当您有一个从其他类继承的类时,这些类的成员不是派生类的成员。它们仍然是其类的成员,派生类继承它们。因此, and 的成员A
仍然是 andB
的成员,A
并且B
在适当的情况下,这仍然反映在它们的类型中。这几乎是 C++ 的核心原则,您只是在实际中观察它。
就像你把一堆书放在书架上一样,这些书中的章节不会成为书架的一部分。它们仍然是书中的相同章节,您的书架是访问它们的途径。
同样,您可以使用C
它来访问其父类的成员,A
并且B
,使用类的名称C
。但它们仍然是 and 的成员A
,B
这反映在它们的类型中。
使用 use 时auto
,您将获得表达式的确切类型。C++ 允许您将指向基类成员的指针转换为指向派生类成员的指针。然而,这是一个转换。使用时不会发生转换,auto
因为这正是auto
它的用途:使用表达式的实际类型,初始化/构造对象,并且不进行任何转换(这里有一些细节增加了一些曲折这里,关于参考文献,但与本次讨论无关)。
推荐阅读
- java - 将 OkHttp 自定义拦截器添加到 Feign 客户端
- php - 使用 PHP 和 MSSQL 准备好的语句
- azure - 如何通过 Azure Function Apps 中的代码直接获取 Azure Function URL?
- python - 尝试在二进制分类上训练 SGDClassifier 时出现位置参数错误
- dart - 避免 BLoC 和 RxDart 中的重复
- typescript - 打字稿“树”对象定义
- javascript - Angular 5 视图子参考在 Safari 中不起作用(v 11.1)
- c++ - 带有通过引用传递的向量的尾递归
- angularjs - ui-router/angular-hybrid - 初始加载/重新加载时无法识别路线
- django - Django注销的问题