為了支持一些編譯時魔法,我想使用指向成員的指標,例如:
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;
}
我不能將指向派生成員的指標作為指向基成員的指標回傳,我用 clang 得到了這個:
cannot initialize return object of type 'TestT::TestTMemPtr' (aka 'BaseT (TestT::*)') with an rvalue of type 'DerivedT TestT::*'
我用gcc檢查了它:
error: invalid conversion from 'DerivedT TestT::*' to 'TestT::TestTMemPtr' {aka '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
}
uj5u.com熱心網友回復:
從繼承的角度來看,BaseT TestT::*andDerivedT TestT::*是兩種不相關的型別1,所以你不能從后者初始化前者,反之亦然,就像你不能int*用 a初始化adouble*因為intanddouble不是基于和派生的類。
1 我的意思是這些型別的兩個物件不指向兩個類,它們是另一個類的基礎。BaseT TestT::*andDerivedT TestT::*都是指標型別,但它們不指向兩個類,其中一個類是另一個類;它們甚至不首先指向類(參見下面的演示代碼),因此指向的型別之間不能有繼承關系,因為繼承是類之間的事情,而不是一般型別之間的事情,例如成員函式型別。
#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
但是,只有當它們都指向類并且這兩個類通過繼承相關時才可能進行指標之間的轉換嗎?
好吧,如果您查看cppreference.com上的Pointer 宣告頁面,它確實有一個關于Pointers to member functions 的部分,它是關于指向成員函式的指標之間的轉換。
但是,它是關于一個的成員函式指標的基類來指向同一個成員函式派生類的,而你似乎尋找一個轉換成員函式指標(的TestT)回傳一個基類(BaseT)的指標同一個類(TestT)的 成員函式回傳一個派生類(DerivedT)。同樣,這兩種型別是無關的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/322673.html
