简体   繁体   中英

Using enum members to templatise member functions

I am writing a class which can be instantiated in different modes. A simple case maybe a meancomputer which can compute different types of means based on the mode.

The class will be instantiated by some other piece of code, and the class code will be generic through function pointers. The specific functions associated with different modes have to be defined and pointers set as per the mode.

What i have looks like this

    enum StatMode { EMA, SMA} ;

    class MeanComputer {
    public:
        MeanComputer ();
        MeanComputer (const MeanComputer& orig);
        virtual ~MeanComputer();
        template <StatMode> double Update (double x);
        template <StatMode> double Sample (double x);
        void Reset();
        void setFunction() { 
            if (mode == EMA ) do_calc = /*EMA mode function*/ ;
        }  
        double (MeanComputer::*do_calc)(double);

    private:
        std::vector <double> window ;
        double mean ;
        double variance ;
        StatMode mode;
    };

    template <StatMode SMA> double MeanComputer::Update(double x) {
    }


    template <StatMode EMA> double MeanComputer::Update(double x) {
    }

However this doesnt seem to compile and gives error error: no matching function for call to 'MeanComputer::Update(double&)'

How do I make this work. I understand one way is to have each such mode function defined by different names, and set the function pointer then. Though that seems to require too much naming, and having cleaner mode template functions seem to be more elegant and easier to understand.

UPDATE: The method of calculating is not set at compile time, but at runtime. however for a given object of the class the mode remains the same, so setting the pointers accordingly will do it once and for all. Also virtual base class also works, but in the actual case a lot of computation is generic, and only some specific or small functions depend on mode. A contrived example maybe the meancomputer takes the update of some kind of coordinate object, and it takes a pair of mode types, the SMA/EMA and latitude/longitude. So one instance maybe aa longitude mean while other is a latitude mean. The full computation is same , just one reads the different member.

template <StatMode SMA> double MeanComputer::Update(double x) {
}

is the wrong syntax

template <> double MeanComputer::Update<SMA>(double x) {
  return 7.0;
}

is how you specialize.

This kind of technique is rarely a good idea.

If you want the method of calculating to be determined at run time, this is entirely the wrong approach, as you need a compile-time constant to be used to determine which Update to call.

You could use a pure virtual base class with template class implementations to remove the need to switch outside of the factory function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM