c++ - virtual functions with compile time constants -


i put question first , add longer explanation below. have following class design not working c++ not support virtual template methods. happy learn alternatives , workarounds implement behaviour.

class localparametersbase { public:   template<unsigned int target>   virtual double get() const = 0;   //<--- not allowed c++ };  template<unsigned int... params> class localparameters : public localparametersbase { public:   template<unsigned int target>   double get() const;               //<--- function should called }; 

using simple function argument instead of template parameter @ moment no alternative following reasons:

  1. the implementation of method in derived class relies on template meta-programming (using variadic class template arguments). far know not possible use function arguments (even if of constant integral type) template arguments.
  2. the method called compile-time constants. performance crucial in application , therefore want benefit calculation @ compile time.
  3. the common base class needed (i have left out rest of interface brevity).

any suggestions highly appreciated.


update: motivation

as there many questions motivation kind of layout, i'll try explain simple example. imagine want measure trajectory in three-dimensional space, in specific example these tracks of charged particles (of fixed mass) in magnetic field. measure these tracks sensitive detectors approximated 2d surfaces. @ each intersection of track sensitive detector, trajectory uniquely identified 5 parameters:

  • two local coordinates describing intersection point of track surface in local coordinate system of detector surface (that's why class names chosen way),
  • two angles specifying direction of trajectory,
  • one parameter containing information momentum , electric charge of particle.

a trajectory therefore identified set of 5 parameters (and associated surface). however, individual measurements consist of first 2 parameters (the intersection point in local 2d coordinate system of surface). these coordinate systems can of different types (kartesian, cylindrical, spherical etc). each measurement potentially constraints different parameters out of full set of 5 parameters (or maybe non-linear combinations of those). nevertheless, fitting algorithm (think of simple chi2 minimizer instance) should not depend of specific type of measurement. needs calculate residuals. looks like

class localparametersbase { public:    virtual double getresidual(const atsvector& fullparameterset) const = 0; }; 

this works fine each derived class knows how map full 5-d parameter set on local coordinate system , can calculate residuals. hope explains bit why need common base class. there other framework related reasons (such existing i/o infrastructure) think of external constraints.
may wondering above example not require have templated get method asking about. base class supposed exposed user. therefore confusing if have list of localparameterbase objects , can fit trajectory using them. can values of measured local parameters. can't access information values measured (which renders previous information useless).

i hope shed light on problem. appreciate comments received far.


for current project writing class main purpose act wrapper around sparse vector of fixed size. instead of storing whole vector (which representation of system state) class has vector of reduced size member variable (= corresponding sub-domain of total parameter space). hope illustration below gives idea of trying describe:

vectortype(5) allparameters = {0.5, 2.1, -3.7, 4, 15/9};   //< full parameter space vectortype(2) subspace      = {2.1, 4};                    //< sub domain storing parameters index 1 , 3 

in order able make connection original vector, need "store" indexes copied "shortened" vector. achieved using non-type variadic template parameters. need able query value of parameter index. should yield compile time error in case parameter not stored in "shortened" vector. simplified code looks like:

template<unsigned int... index> class localparameters { public:   template<unsigned int target>   double get() const;  private:   atsvectorx m_vvalues; };  localparameters<0,1,4> loc; //< ... initialisation ... loc.get<1>();  //< query value of parameter @ index 1 loc.get<2>();  //<-- should yield compile time error parameter @ index 2 not stored in local vector class 

i managed implement behaviour using simple template programming. other parts of code need treat these "shortened" vectors uniformly through 1 interface. still want able access through interface localparametersbase information whether parameter specific index stored (if not want compile time error), , if yes, access value of parameter. in code should similar to

localparametersbase* ploc = new localparameters<0,1,3>(); ploc->get<1>(); 

a suggestion

without more information doing, making educated guesses driving towards approach.

a common performance problem code depends on virtual interface framework provides generic functionality dispatches virtual methods @ high frequency. seems issue facing. have code performing computation on sparse vectors, , want provide generic interface representing each sparse vector happen create.

void compute (localparametersbase *lp) {     // code makes lots of calls lp->get<4>() } 

however, alternative approach make computation generic using template parameter represent derived object type being manipulated.

template <typename sparse> void perform_compute (sparse *lp) {     // code makes lots of calls lp->get<4>() } 

each get<> call in template version of compute against derived object. allows computation occur fast if had written code directly manipulate localparameters<0,1,4>, rather performing dynamic dispatch per get<> call.

if must allow framework control when computation performed, , computation performed on base class, base class version can dispatch virtual method.

class computebase { public:     virtual void perform_compute () = 0; };  void compute (localparametersbase *lp) {     auto c = dynamic_cast<computebase *>(lp);     c->perform_compute(); } 

by using crtp, can create helper class takes derived type template parameter, , implements virtual method passing in derived. thus, computation costs 1 dynamic dispatch, , rest of computation performed on actual sparse vector itself.

template <typename derived> class crtpcompute : public computebase {     void perform_compute () {         auto d = static_cast<derived *>(this);         perform_compute(d);     } }; 

now sparse vector derives helper class.

template <unsigned int... params> class localparameters     : public localparametersbase,       public crtpcompute<localparameters<params...>> { public:     template <unsigned int target> double get() const; }; 

making interface work way have specified it

after results computed, want place resulting sparse vector container later retrieval. however, should no longer performance sensitive operation, can use method described below achieve that.

base template method
→ base template class virtual method
→ derived template method

if wish use polymorphism, delegate template method call in base class virtual function. since template method, virtual function has come template class. can use dynamic cast corresponding template class instance.

template <unsigned int target> class target { public:     virtual double get() const = 0; };  class localparametersbase { public:     virtual ~localparametersbase () = default;     template <unsigned int target> double get() const {         auto d = dynamic_cast<const target<target> *>(this);  // xxx nullptr         return d->get();     } }; 

to automate implementation of virtual methods each target, can again use crtp, passing in derived type helper. helper casts derived type invoke corresponding template method.

template <typename, unsigned int...> class crtptarget;  template <typename derived, unsigned int target> class crtptarget<derived, target> : public target<target> {     double get() const {         auto d = static_cast<const derived *>(this);         return d->template get<target>();     } };  template <typename derived, unsigned int target, unsigned int... params> class crtptarget<derived, target, params...>     : public crtptarget<derived, target>,       public crtptarget<derived, params...> { }; 

and now, inherit appropriately derived class.

template <unsigned int... params> class localparameters     : public localparametersbase,       public crtpcompute<localparameters<params...>>,       public crtptarget<localparameters<params...>, params...> { public:     template <unsigned int target> double get() const; }; 

Comments

Popular posts from this blog

ruby - Trying to change last to "x"s to 23 -

jquery - Clone last and append item to closest class -

c - Unrecognised emulation mode: elf_i386 on MinGW32 -