我想检查提供的模板类是否存在某些方法在编译时。虚构的示例代码:
template <class AudioSystem>
class Car {
public:
Car() {/*nothing related to AudioSystem*/}
void getsCalledLater(AudioSystem* a) {/*...*/}
void Verify() {
// check if class AudioSystem has function double hasFeature(int, double)
// check if class AudioSystem has function double getCreationDate()
}
~Car() {
Verify();
}
};
当调用构造函数时,我没有 AudioSystem
对象,所以我不能只对这些方法进行测试调用。另外:我不能假设 AudioSystem 的默认 ctor 可用。
我在 SO 上已经找到了这个问题,它指向
但我不明白这个无辜的单行解决方案:
// in Validation method:
T* (T::*test)() const = T::Clone; // checks for existence of T* T::Clone() const
感谢任何帮助。
(如果无法访问默认构造函数,我可能会放弃该要求。)
最佳答案
线
T* (T::*test)() const = T::Clone;
声明test
作为指向 T
的常量成员函数的指针,后者不带参数并返回指向 T
的指针.然后它初始化指向 T::Clone
成员函数。现在,如果T::Clone
签名与 (void)->T*
不同或者不存在,那么你会得到一个错误。
非常聪明。
让我们看这个例子:
template<typename T>
class Check // checks for the existence of `T* T::Clone() const`
{
public:
~Check()
{
T* (T::*test)() const = &T::Clone;
// test; // don't think you need this line
}
};
class Foo
{
public:
Foo* Clone() const{}; // try changing the signature, remove `const` for example
};
int main()
{
Check<Foo> testFoo; // ok
}
现在尝试删除 const
来自 Foo::Clone()
的签名, 或者让它返回 int
,你会得到一个编译时错误,因为指针在 Check<T>
中声明不再与正确的函数类型兼容。希望这是有道理的。
请注意,这种验证是在编译时完成的,所以你不能有 bool
返回 true
的函数或 false
(就像您现在尝试做的那样),因为这意味着运行时决策。所以你必须使用这种技巧,如果这个函数存在,那么程序就会编译,如果不存在,你会得到一个编译时错误。
因此,在您的情况下,例如要测试 double AudioSystem::hasFeature(int, double)
是否存在, 你需要声明
double (AudioSystem::*test)(int, double) = AudioSystem::hasFeature;
关于c++ - 检查模板类是否存在函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26983616/