У меня проблема с простым механизмом отражения в C ++. Я хотел бы иметь один тип шаблона, который должен вести себя по-разному с разными указателями на функции-члены в качестве аргументов шаблона:
[Решение № 1, по стандарту это плохо]
Если у меня есть шаблон класса с типом класса и указателем на его функцию-член, я не могу частично специализироваться на нулевом указателе члена, потому что не могу специализировать «аргумент шаблона нетипичного типа с зависимым типом» (см .: https://en.cppreference.com/w/cpp/language/partial_specialization список аргументов [5])
template<class O, void(O::*foo)() = nullptr>
struct p
{};
template<class O, void(O::*foo)()>
struct p<O, nullptr>
{};
[Решение № 2, проблема GCC]
Если я попытаюсь специализироваться на выведенном значении constexpr, которое отражает указатель на член, у меня возникнут различные проблемы с компиляторами. GCC8.2 x64 говорит мне, что выражение nullptr == foo
не является константой в контексте: p<A, &A::f> j;
. Однако ARM GCC8 говорит, что все в порядке. Я думаю, что это некоторая проблема с разметкой памяти, что struct A
не завершено в то время, когда механизм шаблонов пытается оценить конкретный указатель на функцию.
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;
};
[Использование решения № 2, проблема MSVC]
Странно, что MSVC 19.5 x86 в порядке с вышеупомянутым, у него есть другая проблема. Это работает, в то время как структура A является автономной, или она наследует от одной структуры. Но когда есть две базовые структуры (X, Y), он умирает с внутренней ошибкой компилятора.
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 хорошо работает со всем вышеперечисленным.
Может кто-нибудь объяснить, является ли это неопределенным поведением, или в стандарте есть какое-либо руководство по этой теме?