出于实际原因,我有一个类似这样的类
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)
发布于 2013-03-10 06:46:04
您可以通过限定基本成员模板的名称来消除歧义。下面的代码应该可以工作:
template <typename A> struct CRTP
{
template <int (A::*Member)()> int func();
};
struct Base : CRTP<Base>
{
int aMemberOfBase();
};
struct Derived : CRTP<Derived>, Base
{
int aMemberOfDerived();
void foo()
{
CRTP<Derived>::func<&Derived::aMemberOfDerived>();
CRTP<Base>::func<&Base::aMemberOfBase>();
}
};我公开了所有内容,以避免陷入访问控制细节的泥潭。
https://stackoverflow.com/questions/15316699
复制相似问题