如何在编译时检测基类的模板参数(针对错误)
How to detect template parameters of base classes at compile time (for errors)?
我一直在使用奇怪的重复模板模式。一般代码如下:
template <typename T> void genericFunction(T &);
template <typename T> struct Functionality {
void genericMethod() {
genericFunction(*((T *)this)) ;
}
};
struct Klass : public Functionality<Klass> {};
void main() {
Klass obj ;
obj.genericMethod();
}
template <> void genericFunction<Klass>(Klass &obj) {
//do stuff with Klass &obj here
}
我今天遇到了一个错误,花了我大约90分钟的时间来解决这个问题,这个错误是由我的基类继承声明使用了一个不正确的模板参数引起的,有点像这样:
struct Klass : public Functionality<SomeOtherKlass> {}; //SomeOtherKlass wrong!!!
我想增强我的代码,以便检测派生类和基类模板参数之间的不匹配(运行时、编译时、任何时间:),这可能吗?,谢谢
您可以使用Boost或C++11功能在例如genericMethod()
中断言关系:
BOOST_STATIC_ASSERT(( boost::is_base_of<Functionality<T>, T>::value ));
尽管这是假设另一个类也不是从CCD_ 2派生的。
另一种选择是在测试构建的运行时断言关系:
template <typename T> struct Functionality {
#ifdef TEST_BUILD
virtual ~Functionality() {}
#endif
void genericMethod() {
#ifdef TEST_BUILD
assert(dynamic_cast<T*>(this));
#endif
genericFunction(*((T *)this)) ;
}
};
请注意,该测试不会在构造函数和析构函数
在C++11中,以下操作应该有效:
template<typename T> class Base
{
friend T; // allowed in C++11
private:
~Base() {}
public:
// ...
};
class Derived: public Base<Derived> {}; // OK
class WronglyDerived: public Base<Derived> {}; // Error: destructor of base class is private
您可以使用dynamic_cast,如果参数类型错误,它将返回null。(你需要在基础中至少有一个虚拟函数才能工作——比如说析构函数。)
如果你担心效率,boost有一个polymorphic_cast,它在调试模式下进行动态转换,但在生产模式下进行静态转换。
(无论如何,最好避免使用C样式的强制转换。)
假设您向基添加了一个模板化构造函数,该构造函数接受指向任意类型的指针;
template<class U> Functionality(U *) { ... }
然后,每个派生类的构造函数都可以将其this指针传递给构造函数,在构造函数的主体中,您只需静态断言U和T是同一类型。
构造函数参数从未实际使用过,因此应该完全优化。如果这是唯一的基类构造函数,你不能忘记调用它。唯一的问题是,如果你传递了其他的东西。
到目前为止,最明显的建议是使用dynamic_cast在基类构造函数中公开格式错误的继承声明,如下所示:
#include <iostream>
template <typename T> struct Base {
Base() {
std::cout<<dynamic_cast<T *> (this)<<std::endl;
}
virtual void iampolymorphic(){}
};
struct Decoy {} ;
struct Pass : public Base<Pass>{}; //correct
struct Fail : public Base<Decoy>{}; //incorrect
int main() {
Pass p ;
Fail f ;
return 1 ;
}
此代码在g++4.6.1、Amd64 Xubuntu 11.10上编译。两个动态强制转换操作的输出都是空指针。欢迎提出评论、批评和意见。
- C++声明模板参数阴影模板参数错误
- 为什么 CRTP 模板C++给出无效参数错误?
- (C/C++)fscanf_s从txt文件以字符形式读取数组时缺少整数参数错误
- 参数错误可能与类型不匹配有关?
- printf 和 strftime 的参数错误无效
- 如何修复"ctypes"。参数错误:参数 2:<键入"异常.类型错误">:RaspberryPi 中的错误类型"错误
- 如何修复"没有重载函数需要 2 个参数"错误C++
- 术语不计算为函数采用 1 个参数错误?
- 从带有 getline() 的文件读入一行上有多个信息得到无效参数错误
- 为什么我不能像使用 std::string::size_type 那样使用 QList::size_type?(模板参数错误)
- cudaFreeHost() 无效参数错误
- 精神语法不会编译:函数模板参数错误?
- C 功能具有参考参数错误的迭代器错误.寻求解释
- 使用getDefaultCommConfig使用无效的参数错误
- C++ 可变参数模板和模板模板参数:错误:模板参数列表中参数 1 处的类型/值不匹配
- 使用SWIG生成的Python库时,向量分配器参数错误
- 错误C2664:无法转换参数错误
- C 作为参数错误的功能
- 命令行参数错误
- 增强Python参数错误