Reputation: 873
Consider the following example :
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::*'
This example is also available on http://coliru.stacked-crooked.com/a/15f3e7acd8de04a3 , Both clang++ and g++ produce the same error.
How to cast fuu::bax so it is accepted by template tux?
Upvotes: 1
Views: 65
Reputation: 119059
Unfortunately, I don't think there's any way to do this yet. There is an open defect report about this issue. You will have to work around it somehow, such as changing tux
so it accepts int foo::*
instead, or adding another template parameter:
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;
};
Upvotes: 3