Calling derived template class method from base non-template class

Adiel

I'm trying to create the following flow:

Having a 'Base' class, with no params or functionality, just so i can hold Base pointers in a method.

Its derived class, is a template, which implements operator() on given template argument object type.

I'm trying, by using a pointer to base class, call the derived class operator(), in run-time.

I've tried implementing it using CRTP (https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern) But that doesn't seem to work the-other-way-around - when the derived class is a class template.

Here is my code:

class Base {};

template<typename Ref_Obj, typename Obj_Type>
class Derived : public Base {
    private:
        typedef bool (Ref_Obj::*Func_p)(Obj_Type) const;
        Func_p m_func;
        const Ref_Obj& m_db;

    public:
        Derived<Ref_Obj, Obj_Type>(const Ref_Obj& db, Func_p func): m_db(base), m_func(filter) {}

        inline bool operator()(const Obj_Type& obj) const {
            return (m_db.*m_func)(obj);
        }
}

Now, usage is in another class template, that contains vector of Base class pointers, as follows, and have its own operator() :

template<typename Obj_Type2> /* Upon usage, Obj_Type2 is the same as Obj_Type, this is just to differ the two in the code here */
class BlaBla {
    private:
        std::vector<const Base *> m_vec;

    public:
        /* relevant constructors ... */

        inline bool operator()(const Obj_Type2 &obj) const {
            for(std::vector<const Base *>::const_iterator it = m_vec.begin(); it != m_vec.end(); ++it) {

                /*** This is the problematic line V ***/
                if( (*it).operator()(obj) ) { /* DO SOMETHING */ }                    
        }
}

Of course the compiler is complaining that there is no matching function to call for in the problematic line that is marked in the code below, but i can't figure out a way to do the relevant call.

1st Solution that came to mind, is to create a virtual operator()(...), with a specific object type e.g. virtual operator()(const uint32_t &obj) in Base class, which works, but my intention is that operator()(...) will receive a variety of object types, and stating a virtual method for each of them is not elegant and seems to break all the template concept i want to implement here.

2nd Solution that came to mind, is somehow passing Ref_Obj and Obj_Type typenames to Base class, to be used in sort of interface method, that will use static_cast to call the appropriate Derived operator (As in CRTP) - But that doesn't seem to work because Derived class is a class template, and also BlaBla class doesn't directly know Ref_Obj typename.

Is there any other way to make the appropriate call to Deriver operator()

Sam Varshavchik

There is no clear clean way to do this. The fundamental problem is that there is no such thing as a virtual template method.

The cleanest way I can think of doing this that implements complete type erasure is with a dynamic cast, and a virtual method:

class Base {
public:

    virtual bool operator()(const Base &) const=0;
};

template<typename Ref_Obj, typename Obj_Type>
class Derived : public Base {
    private:
        typedef bool (Ref_Obj::*Func_p)(Obj_Type) const;
        Func_p m_func;
        const Ref_Obj& m_db;

    public:
        Derived<Ref_Obj, Obj_Type>(const Ref_Obj& db, Func_p func): m_db(base), m_func(filter) {}

        inline bool operator()(const Base& obj) const override {
            const Obj_Type *derived_obj=dynamic_cast<const Obj_Type *>(&obj);

            if (!derived_obj)
            {
                  throw; // Or maybe return false, or something...
            }
            return (m_db.*m_func)(*derived_obj);
        }
};

Obj_Type must also be derived from Base. This gets the job done at runtime, but there is no compile-time type-checking.

The other approach is to bite the bullet, and forego 100% type erasure:

template<typename Obj_Type>
class Base {
public:

    virtual bool operator()(const Obj_Type &) const=0;
};

template<typename Ref_Obj, typename Obj_Type>
class Derived : public Base<Obj_Type> {
    private:
        typedef bool (Ref_Obj::*Func_p)(Obj_Type) const;
        Func_p m_func;
        const Ref_Obj& m_db;

    public:
        Derived<Ref_Obj, Obj_Type>(const Ref_Obj& db, Func_p func): m_db(base), m_func(filter) {}

        inline bool operator()(const Obj_Type& obj) const override {
            return (m_db.*m_func)(obj);
        }
};

So, you can still abstract away operator() on some object to its pure interface, and define the details in the subclass.

Or, another alternative would be a combination of the two:

class SuperBase {
public:

    virtual bool operator()(const Base &) const=0;
};

template<typename Obj_Type>
class Base : public SuperBase {
public:

    virtual bool operator()(const Obj_Type &) const=0;

    bool operator()(const Base &obj) const override
    {
          // Do the dynamic cast check, and forward it to the other
          // operator().
    }
};

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

How to call constructor of a template base class in a template derived class?

From Dev

Calling virtual method of base template from derived variadic template class

From Dev

Calling a private base method from a derived class in C#

From Dev

Calling protected ctor of inheriting class from within static template method of base class fails

From Dev

Calling method of template base class

From Dev

Visibility of a base class constructor in a derived template class

From Dev

Calling a method from a derived class object that returns a base class pointer

From Dev

Accessing template base class's constructor from derived class

From Dev

Base/Derived template class types

From Dev

overriding the template base method in derived class?

From Dev

Calling a template method on a class template parameter

From Dev

how to extract template derived class's method into non-template base class

From Dev

Deriving a template class from a non-template base

From Dev

Why is template name available in derived class (the base class is an instance of the template)?

From Dev

Derived class from template parameter

From Dev

C++ Check if class derived from template base class; which has integral template parameters

From Dev

Check template parameter of Base class in Derived

From Dev

Calling a method with non-standard-class argument in Freemarker template

From Dev

Template specialization on a non template method in a template class

From Dev

accessing non-template base class virtual function from template derived class

From Dev

Calling derived class method from base class destructor

From Dev

Calling constructor of a template base class from a template derived class

From Dev

C++ templates: Calling member function of derived template class from base class

From Dev

How to derive a non-template class from a template base class

From Dev

Specialize a method form base class in a derived template class

From Dev

How to obtain the derived class type from base when calling a method

From Dev

How to make a non-type template base class with non-template derived class

From Dev

Calling a template function from a template function in a class

From Dev

Using signature of implemented method on Derived class for inherited method from Base class in a "template method pattern" inheritance in Python

Related Related

  1. 1

    How to call constructor of a template base class in a template derived class?

  2. 2

    Calling virtual method of base template from derived variadic template class

  3. 3

    Calling a private base method from a derived class in C#

  4. 4

    Calling protected ctor of inheriting class from within static template method of base class fails

  5. 5

    Calling method of template base class

  6. 6

    Visibility of a base class constructor in a derived template class

  7. 7

    Calling a method from a derived class object that returns a base class pointer

  8. 8

    Accessing template base class's constructor from derived class

  9. 9

    Base/Derived template class types

  10. 10

    overriding the template base method in derived class?

  11. 11

    Calling a template method on a class template parameter

  12. 12

    how to extract template derived class's method into non-template base class

  13. 13

    Deriving a template class from a non-template base

  14. 14

    Why is template name available in derived class (the base class is an instance of the template)?

  15. 15

    Derived class from template parameter

  16. 16

    C++ Check if class derived from template base class; which has integral template parameters

  17. 17

    Check template parameter of Base class in Derived

  18. 18

    Calling a method with non-standard-class argument in Freemarker template

  19. 19

    Template specialization on a non template method in a template class

  20. 20

    accessing non-template base class virtual function from template derived class

  21. 21

    Calling derived class method from base class destructor

  22. 22

    Calling constructor of a template base class from a template derived class

  23. 23

    C++ templates: Calling member function of derived template class from base class

  24. 24

    How to derive a non-template class from a template base class

  25. 25

    Specialize a method form base class in a derived template class

  26. 26

    How to obtain the derived class type from base when calling a method

  27. 27

    How to make a non-type template base class with non-template derived class

  28. 28

    Calling a template function from a template function in a class

  29. 29

    Using signature of implemented method on Derived class for inherited method from Base class in a "template method pattern" inheritance in Python

HotTag

Archive