[英]C++: Calling derived specialised virtual functions within a base template class
假设我有以下模板类:
template<typename T>
class A
{
public:
// Lots of functions...
void someFunc(T obj)
{
// T must implement this function in order to be usable within class A.
obj.interfaceFunc();
}
};
这很好用,因为我将与模板类一起使用的对象实现interfaceFunc()。
但是,如果将指针传递给模板类,则编译会失败,因为取消引用语法不正确。 因为模板类包含许多其他函数,但如果可以帮助的话,我不想将其复制/粘贴到另一个部分专业化中,所以我将类定义更改如下:
template<typename T>
class A
{
public:
// Lots of functions...
virtual void virtualHelperFunction(T* obj)
{
// We should never be here in the base class.
assert(false);
}
void someFunc(T obj)
{
// Call the virtual function.
virtualHelperFunction(&obj);
}
};
// Partial specialisation 1
template<typename T>
class B : public A<T>
{
public:
// ...
virtual void virtualHelperFunction(T* obj)
{
obj->interfaceFunc();
}
};
// Partial specialisation 2
template<typename T*>
class B : public A<T*>
{
public:
// ...
virtual void virtualHelperFunction(T* obj)
{
obj->interfaceFunc();
}
};
但是,当在B的实例上调用virtualHelperFunction()时,但是在父A的someFunc()函数内部时,它将触发断言错误。
B<SomeObject> instance;
instance.someFunc(SomeObject()); // Assertion failure.
我已经尝试过使用函数指针来解决这个问题,但是我对它们还是很陌生,并且非静态指针语法使我有些困惑。 我假设可以定义一个指向virtualHelperFunction()的成员指针,该指针被设置为指向A的构造函数中的基类版本,但随后在B的构造函数中将其覆盖以指向B的函数。 如果是这样,谁能证明正确的语法来做到这一点?
谢谢。
编辑:如果需要上下文,则模板类是一个八叉树节点,该八叉树节点存储类型T的哈希表。所需的接口函数是对象可以返回边界框,以便根据对象是否受限制进行递归插入与树节点的边界相交。
https://github.com/x6herbius/crowbar/blob/qt3d-experimental/Modules/Octree/inc/worldculltreenode.h https://github.com/x6herbius/crowbar/blob/qt3d-experimental/Modules/Octree/inc /worldculltreenode.tcc
这似乎太复杂了。 如果只需要一点点专业知识,为什么还要对整个班级进行专业训练呢? 您只需要一个小的实用程序,上面写着“如果是指针,请取消引用,否则请不要使用它”。 它可能看起来像这样:
template <typename T>
T& deref_if_pointer(T& t) { return t; }
template <typename T>
T& deref_if_pointer(T* t) { return *t; }
// ...
void someFunc(T obj) {
deref_if_pointer(obj).interfaceFunc();
}
您也可以轻松地将deref_if_pointer
扩展到各种智能指针; 只需添加另一个重载。
我不太确定要完成什么,所以我不得不猜测。 以下内容不能满足您的问题?
class A
{
public:
// Lots of functions...
void someFunc(T* obj)
{
// T must implement this function in order to be usable within class A.
obj->interfaceFunc();
}
void someFunc(T obj)
{
// T must implement this function in order to be usable within class A.
obj.interfaceFunc();
}
};
如果要这样做,则需要在第一个部分专业化中使用引用而不是指针:
template<typename T>
class A
{
public:
// Lots of functions...
virtual void virtualHelperFunction(T* obj)
{
// We should never be here in the base class.
assert(false);
}
void someFunc(T obj)
{
// Call the virtual function.
virtualHelperFunction(&obj);
}
};
// Partial specialisation 1
template<typename T>
class B : public A<T>
{
public:
// ...
virtual void virtualHelperFunction(T& obj)
{
obj.interfaceFunc();
}
};
// Partial specialisation 2
template<typename T*>
class B : public A<T*>
{
public:
// ...
virtual void virtualHelperFunction(T* obj)
{
obj->interfaceFunc();
}
};
您的代码无法编译。 template<typename T*>
是非法的,并且您没有声称的任何部分专业化知识。
这有效:
template<typename T>
class A
{
public:
// Lots of functions...
virtual void virtualHelperFunction(T* obj)
{
// We should never be here in the base class.
assert(false);
}
void someFunc(T obj)
{
// Call the virtual function.
virtualHelperFunction(&obj);
}
};
// Unspecialized template
template<typename T>
class B : public A<T>
{
public:
// ...
virtual void virtualHelperFunction(T* obj)
{
obj->interfaceFunc();
}
};
// Partial specialisation
template<typename T>
class B<T*> : public A<T*>
{
public:
// ...
virtual void virtualHelperFunction(T** obj)
{
(*obj)->interfaceFunc();
}
};
int main() {
B<SomeObject> instance1;
instance1.someFunc(SomeObject());
B<SomeObject*> instance2;
SomeObject x;
instance2.someFunc(&x);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.