По практическим причинам, у меня есть класс, какНаследование и CRTP
template <class A>
class CRTP
{
template <int (A::*Member)()>
int func(void * obj)
{
int result
// Do something with Member, like
// result = (reinterpret_cast<A*>(obj)->*Member)();
return result;
}
};
template <void (A::*Member)()>
является требование, оно не может быть передан в качестве аргумента.
И у меня есть базовый класс
class Base : public CRTP<Base>
{
int aMemberOfBase() {...}
};
и ее производная, которые я хочу также наследовать CRTP
class Derived : public CRTP<Derived>, public Base
{
int aMemberOfDerived() {...}
};
В некотором члене производные, я сделаю что-то вроде
func<&Derived::aMemberOfDerived>(this);
func<&Base::aMemberOfBase>(this);
Возможно ли это?
(Ну, VC++ скомпилировать только первую строку и не хочет читать о втором ... но производные должен иметь член
template <int (Base::*Member)()> int func(void * obj);
template <int (Derived::*Member)()> int func(void * obj);
который выглядит странно, я признаю это. Но следующий фрагмент кода
template <void (Base::*Member)()> int func() {return 0;}
template <void (Derived::*Member)()> int func() {return 1;}
компилирует и вернуть func<&Base::someMember>() != func<&Derived::someMember>()
, потому что подпись шаблона не то же самое, и не может быть такой же.)
Я должен признать, что я не хорошо награждаю то, что говорит стандарт. Но является ли модель наследования, которую я пытаюсь разрешить? И если да, почему одна из строк не компилируется?
Кроме того, если я объявляю
class Derived : public Base, public CRTP<Derived>
вместо
class Derived : public CRTP<Derived>, public Base
Я получаю компиляции ошибки времени (на всех func<...>(...)
), что означает, что есть что-то не так-то.
С другой стороны, я знаю, что
template <class A, int (A::*Member)()> int func(void * obj)
устранило бы необходимость в CRTP, но болезненные писать func<Derived, &Derived::aMember>()
. Существует ли такое решение, как
template <class Class, void (Class::*Member)()> class A
{
void func(void * obj) {...(reinterpret_cast<Class*>(obj)->*Member)();...}
};
template <typename Signature> class B;
template <typename Class, typename Member>
class B<&Class::Member> : public class A<Class, &Class::Member> {};
которое позволило бы B<&Base::Derived>().func(somePtrToBase)
?
Ну, после прочтения несвязанных статей, кажется, что Дон Клугстон в своем «самом быстром делетете» столкнулся с теми же проблемами. Поэтому я решил отказаться от CRTP и повторить аргументы. Спасибо за вашу помощь. – Fred