假设我有以下模板类:
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();
}
};
但是,当调用 virtualHelperFunction()时,在B的实例上,但是当在父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
答案 0 :(得分:1)
这似乎太复杂了。如果你只需要一点点专门的话,为什么要专注于全班?你需要的只是一个小实用程序,如果它是一个指针,则说“取消引用它,否则不管它”。它看起来像这样:
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
扩展到各种智能指针;只是添加另一个重载。
答案 1 :(得分:0)
我不确定你想要完成什么,所以我不得不猜测。以下哪种方式不能满足您的问题?
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();
}
};
答案 2 :(得分:0)
如果你想这样做,那么你需要在第一个部分专业化中使用引用而不是指针:
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();
}
};
答案 3 :(得分:0)
您的代码无法编译。 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);
}