【发布时间】:2021-12-03 18:30:41
【问题描述】:
为了支持一些编译时魔法,我想使用指向成员的指针,例如:
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
}
【问题讨论】:
-
无关的,
using TestTMemPtr = BaseT TestT::* ;而不是那个丑陋的typedef。 -
显然它不是生产代码,但你是对的 :)
标签: c++ c++11 metaprogramming compile-time