简体   繁体   English

“指向成员的派生指针”到“指向成员的基指针”错误

[英]"Derived pointer to member" to "base pointer to member" error

To support some compile time magic I would like to use pointers to members like:为了支持一些编译时魔法,我想使用指向成员的指针,例如:

struct BaseT
{
};

struct DerivedT: public BaseT
{
};

struct TestT 
{
    DerivedT testMem;

    typedef BaseT (TestT::* TestTMemPtr);

    constexpr TestT() = default;

    static constexpr TestTMemPtr testMemOffset()
    {
        return &TestT::testMem;
    }
};

int main()
{
    constexpr TestT test;
}

I cannot return a pointer-to-derived-member as a pointer-to-base-member, I get this with clang:我不能将指向派生成员的指针作为指向基成员的指针返回,我用 clang 得到了这个:

cannot initialize return object of type 'TestT::TestTMemPtr' (aka 'BaseT (TestT::*)') with an rvalue of type 'DerivedT TestT::*'

I checked it with gcc:我用gcc检查了它:

error: invalid conversion from 'DerivedT TestT::*' to 'TestT::TestTMemPtr' {aka 'BaseT TestT::*'}

Is this the normal behavior?这是正常行为吗? I thought I can always use a derived pointer as a base pointer.我以为我总是可以使用派生指针作为基指针。

UPDATE : Ok, the original example wasn't the best, I think this one is more expressive, so DerivedT* can be used as BaseT* , but DerivedT TestT::* cannot be used as BaseT TestT::* :更新:好的,原来的例子不是最好的,我认为这个更具表现力,所以DerivedT*可以用作BaseT* ,但DerivedT TestT::*不能用作BaseT TestT::*

struct BaseT
{
};

struct DerivedT: public BaseT
{
};

struct TestT 
{
    DerivedT m_test;
};

using BaseTMemPtr = BaseT TestT::*;

int main()
{
    TestT test;
    BaseT* simplePtr = &test.m_test; //It is DerivedT*, but can be used as BaseT*
    BaseT (TestT::*memPtr) = &TestT::m_test; //Error, BaseT TestT::* cannot be used as DerivedT TestT::*
    BaseTMemPtr memPtr2 = &TestT::m_test; //Error, just the same
}

From the point of view of inheritance, BaseT TestT::* and DerivedT TestT::* are two unrelated types¹, so you can't initialize the former from the latter nor vice versa, just like you can't initialize a int* with a double* because int and double are not based and derived classes.从继承的角度来看, BaseT TestT::*DerivedT TestT::*是两个不相关的类型¹,所以不能从后者初始化前者,反之亦然,就像不能用初始化int* a double*因为intdouble不是基于类和派生类。


¹ By that I mean that two objects of these types don't point to two classes which are one the base of another. ¹ 我的意思是这些类型的两个对象不指向两个类,它们是另一个类的基础。 BaseT TestT::* and DerivedT TestT::* are both pointer types, but they don't point to two classes of which one is base of the other; BaseT TestT::*DerivedT TestT::*都是指针类型,但它们不指向两个类,其中一个是另一个的基类; they don't even point to classes in the first place (see demo code below), so there can be no inheritance relation between the pointed-to types, as inheritance is a thing between classes , not between types in general, such as member function types.它们甚至不首先指向类(参见下面的演示代码),因此指向的类型之间不能有继承关系,因为继承是之间的事情,而不是一般类型之间的事情,例如成员函数类型。

#include <type_traits>
struct BaseT { };

struct DerivedT: public BaseT { };

struct TestT { };

template<typename T, typename = void>
struct points_to_class : std::false_type {};
template<typename T>
struct points_to_class<T*> : std::is_class<T> {};

static_assert(points_to_class<BaseT*>::value); // passes
static_assert(points_to_class<BaseT TestT::*>::value); // fails

But so, is the conversion between pointers only possible when they both point to classes and those two classes are related by inheritance?但是,只有当它们都指向类并且这两个类通过继承相关时才可能进行指针之间的转换吗?

Well, if you give a look at the Pointer declaration page on cppreference.com , it does have a section on Pointers to member functions , and it is about conversion between pointers to member functions.好吧,如果您查看cppreference.com上的Pointer 声明页面,它确实有一个关于Pointers to member functions 的部分,它是关于指向成员函数的指针之间的转换。

But it is about of a pointer to member function of a base class to pointer to the same member function of a derived class , whereas you seem to look for converting a pointer to member function (of TestT ) returning a base class ( BaseT ) to a pointer to member function of the same class ( TestT ) returning a derived class ( DerivedT ) .但它是关于指向基类成员函数指针指向派生类的同一成员函数指针,而您似乎在寻找将指向成员函数( TestT指针转换为返回基类( BaseT指向返回派生类 ( DerivedT )的同一类 ( TestT ) 的成员函数指针 Again, the two types are unrelated.同样,这两种类型是无关的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM