[英]How to avoid errors while using CRTP?
使用CRTP有时我会编写如下代码:
// this was written first
struct Foo : Base<Foo, ...>
{
...
};
// this was copy-pasted from Foo some days later
struct Bar : Base<Foo, ...>
{
...
};
并且很难理解出现了什么问题,直到我在调试器中跟踪代码并看到Bar的成员未在Base
。
如何在编译时显示此错误?
(我使用MSVC2010,所以我可以使用一些C ++ 0x功能和MSVC语言扩展)
在C ++ 0x中,您有一个简单的解决方案。 我不知道它是否在MSVC10中实现。
template <typename T>
struct base
{
private:
~base() {}
friend T;
};
// Doesn't compile (base class destructor is private)
struct foo : base<bar> { ... };
你可以使用这样的东西:
template<class T> class Base {
protected:
// derived classes must call this constructor
Base(T *self) { }
};
class Foo : public Base<Foo> {
public:
// OK: Foo derives from Base<Foo>
Foo() : Base<Foo>(this) { }
};
class Moo : public Base<Foo> {
public:
// error: constructor doesn't accept Moo*
Moo() : Base<Foo>(this) { }
};
class Bar : public Base<Foo> {
public:
// error: type 'Base<Bar>' is not a direct base of 'Bar'
Bar() : Base<Bar>(this) { }
};
template<typename T, int arg1, int arg2>
struct Base
{
typedef T derived_t;
};
struct Foo : Base<Foo, 1, 2>
{
void check_base() { Base::derived_t(*this); } // OK
};
struct Bar : Base<Foo, 1, 2>
{
void check_base() { Base::derived_t(*this); } // error
};
此代码基于Amnon的答案 ,但检查代码不包含派生类的名称,因此我可以复制并粘贴它而不进行更改。
无法知道派生类型。 你可以强制执行Foo
来源于Base<Foo>
,但你不能强制执行,没有其他类也从中导出。
我可以使用宏
#define SOMENAMESPACE_BASE(type, arg1, arg2) type : Base<type, arg1, arg2>
但如果存在更好的解决方案,我不想使用宏。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.