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 declarations empty, 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

Popular posts from this blog

powershell Start-Process exit code -1073741502 when used with Credential from a windows service environment -

twig - Using Twigbridge in a Laravel 5.1 Package -

c# - LINQ join Entities from HashSet's, Join vs Dictionary vs HashSet performance -