c++ - Compile-time pure virtual functions -
i've tried implementing list container, , decided move general functions sum()
base class, can reuse them later in other containers.
all base support class needs 3 methods empty()
, head()
, tail
. can't make pure virtual because support class never instantiated. still has use methods implement own methods sum()
.
i tried this:
#include <iostream> using namespace std; template<typename t> class statssupport { public: t sum(void) const { if (empty()) { return t(0); } else { return head() + tail()->sum; } } // other methods }; template<typename t> class list : public statssupport<t> { public: // constructors etc. bool empty(void) const {return head_ != null;} const t& head(void) const {return *head_;} const list<t>& tail(void) const {return *tail_;} // other methods private: t* head_; list<t> *tail_; };
but trying use sum()
gets me compilation error
prog.cpp:8:13: error: there no arguments 'empty' depend on template parameter, declaration of 'empty' must available [-fpermissive] if (empty()) { ^
for each of empty()
, head()
, tail()
.
any advice?
the problem statssupport
cannot find empty
, head
etc. functions because these neither exist in nor in global scope. statssupport
not know functions exist in derived class.
basically there 2 ways solve this:
- runtime polymorphism, add virtual destructor
statssupport
, add declarationsempty
,head
etc. pure virtual. - compile time polymorphism via using crtp mentioned in comments. focus on latter.
so statssupport
needs way access functions of derived class. can done adding type of derived class template parameter, called crtp:
template<class derived, typename t> class statssupport { public: t sum(void) const { if (derived()->empty()) { return t(0); } else { return derived()->head() + derived()->tail()->sum; } } // other methods private: derived *derived() { return static_cast<derived*>(this); } const derived *derived() const { return static_cast<const derived*>(this); } }; template<typename t> class list : public statssupport<list<t>, t> { // changes simplified statssupport<list<t>> ouf of scope of question
i using function derived
instead of member keep class const correct.
of course alternative different design relying on algorithms. there move sum
, other functions of statssupport
global namesapce , access them sum(my_container_instance)
. more stl way use iterators. use std::accumulate
summing.
Comments
Post a Comment