Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/136.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将指向成员的指针强制为最派生的类型_C++_C++11_Pointer To Member - Fatal编程技术网

C++ 将指向成员的指针强制为最派生的类型

C++ 将指向成员的指针强制为最派生的类型,c++,c++11,pointer-to-member,C++,C++11,Pointer To Member,考虑以下类型层次结构: struct A { int x; }; struct B : A { int y; }; &B::y的类型是intb:*,而&B::x的类型是inta:*。它可以转换为intb::*,这正是我需要的,但我需要显式地执行转换 是否有一种简便的方法将类型推断为指向我指定的类的成员的指针?毕竟,如果我想要一个A::*到x我可以做&A::x 这种转换在虚拟继承的情况下是不可能的。假定 struct A { int x; }; struct B : vi

考虑以下类型层次结构:

struct A {
    int x;
};

struct B : A {
    int y;
};
&B::y
的类型是
intb:*
,而
&B::x
的类型是
inta:*
。它可以转换为
intb::*
,这正是我需要的,但我需要显式地执行转换


是否有一种简便的方法将类型推断为指向我指定的类的成员的指针?毕竟,如果我想要一个
A::*
x
我可以做
&A::x

这种转换在虚拟继承的情况下是不可能的。假定

struct A {
  int x;
};

struct B : virtual A {
  int y;
};
两个功能,

int f(B* pB) {
  int A::*pX = &A::x; // or &B::x, identical but clearer this way
  return pB->*pX;
}

int g(B* pB) {
  int B::*pY = &B::y;
  return pB->*pY;
}
f(B*)
需要进行vtable查找,以便在
*pB
中找到
a
实例的基指针,而
g(B*)
只对
pB
应用偏移量。因此,对象
&A::x
不能表示为类型
int B:*
的实例,它需要一个不同的运行时逻辑来使用指向
B
的指针进行计算,而不是
int B:*
的运行时逻辑

尽管
B
是目前派生最多的类,但是可以定义另一个类
C
在不同的编译单元中继承
A
B
,并将
C*
传递给
f()
。因此,
A
B
内的偏移量不能作为固定值


有人可能会说,如果不存在虚拟继承,或者在匿名名称空间中,或者。。。但可能更容易坚持不允许它。

一个“方便的方法”?背景是什么?像
bikeshed([](自动包装){return&unwrap::x;})
这样的奇怪表达式是否方便?编辑:OOPS,那是C++14@dyp只想避免编写类似于
template T-Derived::*to_-Derived(T-CLS::*member)
的东西,因为
to-u-Derived(&B::x)
的名称很长时,键入有点烦人。我只是希望我遗漏了一些聪明的方法。您可以尝试推断非多态lambda的
操作符()
,然后
bikeshed([](标记d){return&unwrap::x})
。如果只有一小部分成员名,比如
x
,那么对于某些帮助对象
x\u name
,当然可以使用
bikeshed(x\u name)
。您仍然可以使用
#将成员ptr(C,m)定义为派生(&C::m)
@Jarod42是的,这就是我最终得到的结果。似乎是类型系统的一个奇怪方面不?