When implementing an iterator interface for a generic data type, I encountered the following recommendation: "... do not put virtual functions in a class template, unless you want all virtual functions to be instantiated (as opposed to non-virtual functions of template types)" [ C ++ Programming Standards, Recommendation No. 64 (Sutter, Allesandrescu) http://programming-lang.com/ru/comp_programming/satter/0/j133.html ]
For these reasons, I redid my old code:
template<class Item> class IIterator { public: virtual ~IIterator(); virtual void First() = 0; virtual void Next() = 0; virtual bool IsDone() const = 0; virtual Item * CurrentItem() const = 0; protected: IIterator(); } //... template<class T> class IteratorList: public IIterator<T> { ... } in the following way:
class IIterator { public: virtual ~IIterator(); virtual void First() = 0; virtual void Next() = 0; virtual bool IsDone() const = 0; template<class Item> Item * CurrentItem() const { return nullptr; } protected: IIterator(); }; //... template<class T> class IteratorList: public IIterator { ... } As I understand it, my second edition of the iterator interface will allow:
- separately compile modules that inherit this interface
- avoid overriding my generic type
Did I understand and apply the above recommendation correctly?
Interesting, but if you implement CurrentItem as follows:
template<class Item> Item* IIterator::CurrentItem() { assert(!"Incorrectly overridden"); return nullptr; } it seems to me and the template:
template<class Item> Item * CurrentItem() const; and virtual:
virtual Item * CurrentItem() const = 0; options CurrentItem wakes up equally fulfill your contract? Well, of course, except that the warning in the template version can only occur at the execution stage.