如何将指向 base class 成员的指针转换为指向 derived class 相同成员的指针
How to cast a pointer to member of base class to a pointer to the same member of derived class
考虑以下示例:
struct foo {
int bax;
};
struct fuu : foo {
};
template<int foo::*>
struct tox {};
template<int fuu::*>
struct tux {};
int foo::* xo = &foo::bax;
int fuu::* xu = &fuu::bax; // works
typedef int foo::*boz;
typedef tox<&foo::bax> qox;
typedef tux<&fuu::bax> qux; // fails: 'int foo::*' cannot be converted to a value of type 'int fuu::*'
typedef tux<(boz)&fuu::bax> qux; // fails: non-type template argument of type 'boz' (aka 'int foo::*') cannot be converted to a value of type 'int fuu::*'
此示例在 http://coliru.stacked-crooked.com/a/15f3e7acd8de04a3 上也可用,clang++ 和 g++ 都会产生相同的错误。
如何转换 fuu::bax 使其被模板 tux 接受?
不幸的是,我认为目前还没有办法做到这一点。关于这个问题有一个open defect report。您将不得不以某种方式解决它,例如更改 tux
以便它接受 int foo::*
,或者添加另一个模板参数:
template <typename T, int T::* arg>
struct tux {
static_assert(std::is_convertible<int T::*, int fuu::*>::value,
"T must be an unambiguous accessible base of fuu");
// note that this still works
// however, you won't be able to use it as a template argument
static constexpr int fuu::* pm = arg;
};
考虑以下示例:
struct foo {
int bax;
};
struct fuu : foo {
};
template<int foo::*>
struct tox {};
template<int fuu::*>
struct tux {};
int foo::* xo = &foo::bax;
int fuu::* xu = &fuu::bax; // works
typedef int foo::*boz;
typedef tox<&foo::bax> qox;
typedef tux<&fuu::bax> qux; // fails: 'int foo::*' cannot be converted to a value of type 'int fuu::*'
typedef tux<(boz)&fuu::bax> qux; // fails: non-type template argument of type 'boz' (aka 'int foo::*') cannot be converted to a value of type 'int fuu::*'
此示例在 http://coliru.stacked-crooked.com/a/15f3e7acd8de04a3 上也可用,clang++ 和 g++ 都会产生相同的错误。
如何转换 fuu::bax 使其被模板 tux 接受?
不幸的是,我认为目前还没有办法做到这一点。关于这个问题有一个open defect report。您将不得不以某种方式解决它,例如更改 tux
以便它接受 int foo::*
,或者添加另一个模板参数:
template <typename T, int T::* arg>
struct tux {
static_assert(std::is_convertible<int T::*, int fuu::*>::value,
"T must be an unambiguous accessible base of fuu");
// note that this still works
// however, you won't be able to use it as a template argument
static constexpr int fuu::* pm = arg;
};