How to avoid errors while using CRTP?
有时我使用crtp编写这样的代码:
1 2 3 4 5 6 7 8 9 10 11 | // this was written first struct Foo : Base<Foo, ...> { ... }; // this was copy-pasted from Foo some days later struct Bar : Base<Foo, ...> { ... }; |
在我跟踪调试器中的代码并发现在
如何在编译时显示此错误?
(我使用MSVC2010,所以我可以使用一些C++0x特性和MSVC语言扩展)
在C++ 0x中,你有一个简单的解决方案。但我不知道它是否在MSVC10中实现。
1 2 3 4 5 6 7 8 9 10 | template <typename T> struct base { private: ~base() {} friend T; }; // Doesn't compile (base class destructor is private) struct foo : base<bar> { ... }; |
您可以使用如下内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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) { } }; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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的答案,但是检查代码不包含派生类的名称,所以我可以复制粘贴它而不做任何更改。
我可以用宏
1 | #define SOMENAMESPACE_BASE(type, arg1, arg2) type : Base<type, arg1, arg2> |
但如果存在更好的解决方案,我不想使用宏。
无法知道派生类型。可以强制执行从