I have a problem with a simple reflection like mechanism in C++. I would like to have one template type, which should behave differently with different member function pointers as template arguments:
If I have a class template with a class type and its member function pointer, I cannot specialize partially to the member pointer being null, because I cannot specialize "non-type template argument with dependent type" (see: https://en.cppreference.com/w/cpp/language/partial_specialization argument list [5])
template<class O, void(O::*foo)() = nullptr>
struct p
{};
template<class O, void(O::*foo)()>
struct p<O, nullptr>
{};
If I try to specialize to a deduced constexpr value, which reflects to the member pointer, I have different problems with the compilers. GCC8.2 x64 tells me that the nullptr == foo
expression is not constant in the context: p<A, &A::f> j;
. However ARM GCC8 says it is okay. I think it is some memory layout problem, that struct A
is not complete at the time the template engine tries to evaluate a concrete function pointer.
template<class O, void(O::*foo)() = nullptr, bool = nullptr == foo>
struct p
{};
template<class O, void(O::*foo)()>
struct p<O, foo, true>
{};
struct A
{
void f();
p<A, &A::f> j;
};
It is strange that MSVC 19.5 x86 is okay with the above, it has another problem. It is working, while struct A is standalone, or it inherits from one struct. But when there are two base structs (X, Y), it dies with internal compiler error.
template<class O, void(O::*foo)() = nullptr, bool = nullptr == foo>
struct p
{};
template<class O, void(O::*foo)()>
struct p<O, foo, true>
{};
struct X{};
struct Y{};
struct A : X, Y
{
void f();
p<A> i;
p<A, &A::f> j;
};
Clang7 works with all the above well.
Can anyone explain, if this is an undefined behavior, or is there any guide about this topic in the standard?
Aucun commentaire:
Enregistrer un commentaire