Can a class member function template be virtual?

前端 未结 13 968
旧时难觅i
旧时难觅i 2020-11-22 03:29

I have heard that C++ class member function templates can\'t be virtual. Is this true?

If they can be virtual, what is an example of a scenario in which one would

13条回答
  •  太阳男子
    2020-11-22 04:00

    In the other answers the proposed template function is a facade and doesn't offer any practical benefit.

    • Template functions are useful for writing code only once using different types.
    • Virtual functions are useful for having a common interface for different classes.

    The language doesn't allow virtual template functions but with a workaround it is possible to have both, e.g. one template implementation for each class and a virtual common interface.

    It is however necessary to define for each template type combination a dummy virtual wrapper function:

    #include 
    #include 
    #include 
    
    //---------------------------------------------
    // Abstract class with virtual functions
    class Geometry {
    public:
        virtual void getArea(float &area) = 0;
        virtual void getArea(long double &area) = 0;
    };
    
    //---------------------------------------------
    // Square
    class Square : public Geometry {
    public:
        float size {1};
    
        // virtual wrapper functions call template function for square
        virtual void getArea(float &area) { getAreaT(area); }
        virtual void getArea(long double &area) { getAreaT(area); }
    
    private:
        // Template function for squares
        template 
        void getAreaT(T &area) {
            area = static_cast(size * size);
        }
    };
    
    //---------------------------------------------
    // Circle
    class Circle : public Geometry  {
    public:
        float radius {1};
    
        // virtual wrapper functions call template function for circle
        virtual void getArea(float &area) { getAreaT(area); }
        virtual void getArea(long double &area) { getAreaT(area); }
    
    private:
        // Template function for Circles
        template 
        void getAreaT(T &area) {
            area = static_cast(radius * radius * 3.1415926535897932385L);
        }
    };
    
    
    //---------------------------------------------
    // Main
    int main()
    {
        // get area of square using template based function T=float
        std::unique_ptr geometry = std::make_unique();
        float areaSquare;
        geometry->getArea(areaSquare);
    
        // get area of circle using template based function T=long double
        geometry = std::make_unique();
        long double areaCircle;
        geometry->getArea(areaCircle);
    
        std::cout << std::setprecision(20) << "Square area is " << areaSquare << ", Circle area is " << areaCircle << std::endl;
        return 0;
    }
    

    Output:

    Square area is 1, Circle area is 3.1415926535897932385

    Try it here

提交回复
热议问题