如果我理解正确的话,您需要确保某些方法在最终的派生类中实现,但不使用经典方式(抽象继承),因为它太重了。
我的第一个想法是简单地声明而不是定义方法
template <typename T>
struct ForwardIterator {
T operator++ ();
T operator++ (int);
};
所以当你使用这些方法时
MyCustomRandomAccessIterator i;
++i;
你会得到一个链接器错误。
但是,只有当您使用忘记的方法时,您才会收到链接器错误(我想您更喜欢编译错误),因此,如果您忘记了单个方法,则可能很难检测到它(您需要将其与对象一起使用)。
所以我的想法,也许并不完美,是delete
方法,添加构造函数并检查最终类中方法是否存在。
我的意思是...就像
template <typename T>
struct ForwardIterator {
T operator++ () = delete;
T operator++ (int) = delete;
ForwardIterator ()
{
static_assert( sizeof(decltype(std::declval<T>()++)), "!" );
static_assert( sizeof(decltype(++std::declval<T>())), "!" );
}
};
这样你就可以获得所有编译错误(如果你愿意的话,也许,带有有意义的错误消息,比"!"
)简单地声明你的类的一个对象
MyCustomRandomAccessIterator i;
// ++i; // no needs of invoke the forgotten methods to get the errors
以下是完整的编译示例
#include <utility>
template <typename T>
struct ForwardIterator {
T operator++ () = delete;
T operator++ (int) = delete;
ForwardIterator ()
{
static_assert( sizeof(decltype(std::declval<T>()++)), "!" );
static_assert( sizeof(decltype(++std::declval<T>())), "!" );
}
};
template <typename T>
struct BidirectionalIterator: public ForwardIterator<T> {
T operator-- () = delete;
T operator-- (int) = delete;
BidirectionalIterator ()
{
static_assert( sizeof(decltype(std::declval<T>()--)), "!" );
static_assert( sizeof(decltype(--std::declval<T>())), "!" );
}
};
template <typename T>
struct RandomAccessIterator: public BidirectionalIterator<T>{
T operator+ (int) = delete;
T operator- (int) = delete;
RandomAccessIterator ()
{
static_assert( sizeof(decltype(std::declval<T>()+0)), "!" );
static_assert( sizeof(decltype(std::declval<T>()-0)), "!" );
}
};
// Custom Iterator Implementation
struct MyCustomRandomAccessIterator
: public RandomAccessIterator<MyCustomRandomAccessIterator> {
// with `if 0` (forgetting definition of requested methods) you get
// a lot of compilation errors
#if 1
MyCustomRandomAccessIterator operator++ ()
{ return *this; }
MyCustomRandomAccessIterator operator++ (int)
{ return *this; }
MyCustomRandomAccessIterator operator-- ()
{ return *this; }
MyCustomRandomAccessIterator operator-- (int)
{ return *this; }
MyCustomRandomAccessIterator operator+ (int)
{ return *this; }
MyCustomRandomAccessIterator operator- (int)
{ return *this; }
#endif
};
int main()
{
// simply declaring i you get a lot of errors, in case of no
// methods definitions
MyCustomRandomAccessIterator i;
}