指向派生成员的指针到成员

时间:2018-01-28 06:21:27

标签: c++

是否存在允许引用派生成员实例的指针成员的语法,即成员本身而不是包含对象。

如果我执行以下操作:

struct Base1
{
    int m;
};
struct Derived : Base1
{
    int n;
};
struct Base2
{
    Base1 b;
    Derived d;
};

void foo()
{
    Base1 Base2::*ptr1 = &Base2::b ;// okay
    Base1 Base2::*ptr2 = &Base2::d; // error
}

我得到的错误是:

error C2440: 'initializing': cannot convert from 'Derived Base2::* ' to 'Base1 Base2::* '
note: Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

有没有合理的方法来做到这一点而不需要演员? (如果可能的话,我不想在这里使用模板,因为实际的类型需要保存在当前的调用链之外)。

2 个答案:

答案 0 :(得分:0)

我不知道这是否违反了“无模板”政策,但可以使std::variant保留指针类型。

using ptm_type = std::variant<Base1 Base2::*, Derived Base2::*>;
ptm_type ptr1 = &Base2::b ;// okay
ptm_type ptr2 = &Base2::d; // okay too

由于我假设您希望以相同的方式处理Base1Derived个对象(否则为什么会这样做),然后您可以将代码包装到std::visit的调用中以进行统一访问

std::visit([](auto& p1){
  // Do your thing
}, ptr1);

虽然这只是伪装的另一个模板。

答案 1 :(得分:0)

我不认为您的问题是您访问派生成员对象。这是你声明它是错误的类型。您的第二个指针应声明如下:

Derived Base2 :: * ptr2 =&amp; Base2 :: d; //好的

您是否专门尝试将指针的派生类语义的基指针应用于指针?这不起作用,它必须匹配确切的类型。您甚至无法执行任何简单的转换,例如声明指向void的指针,该指针指向指向int成员的指针。

如果您愿意,可以在将指向成员的指针绑定到其实例后,使用新的赋值通过公共基类指针执行任何公共访问。