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

409 views Asked by At
#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?

1

There are 1 answers

0
leslie.yao On BEST ANSWER

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.