Search code examples
c++c++11templatestype-conversiondynamic-cast

How to access child member from parent's template function?


#include <iostream>
#include <functional>

using namespace std;

class Child;

class Parent {
    public:
    template <class Function, class... Args>
    void f(Function&& f, Args&&... args)
    {
        Child *c = dynamic_cast<Child*>(this);
        cout << c->n;
    }
};

class Child : public Parent {

public:
    int n = 0;
};

int main()
{
    Parent *p = new Child();
    cout << "abc";
    return 0;
}

The code intends to access child class's member from parent's template member function. I'd like to do this because the template member function cannot be virtual. The error I got is: "'Child' is an incomplete type". How do I make this work?


Solution

  • You can separate f's definition and declaration, and move the definition after the definition of class Child. e.g.

    class Child;
    
    class Parent {
    public:
        virtual ~Parent() = default;          // must be polymorphic type
        template <class Function, class... Args>
        void f(Function&& f, Args&&... args); // the declaration
    };
    
    class Child : public Parent {
    public:
        int n = 0;
    };
    
    // the definition
    template <class Function, class... Args>
    void Parent::f(Function&& f, Args&&... args)
    {
        Child *c = dynamic_cast<Child*>(this);
        if (c != nullptr)                     // check the result of conversion
            cout << c->n;
    }
    

    Note that

    1. the base class Parent must be polymorphic type to use dynamic_cast; i.e. it must have at least one virtual function.
    2. You'd better check the result of dynamic_cast before using it.