Question

Suppose I have a host class that holds a member:

template<class p1, class p2>
struct host : public p1, public p2 {
 double member;
};

and I want to use the same member in p1 and p2:

struct p1 {
  void f1() { host::member+=1;} // this is incorrect but I'm looking for this behavior
};
struct p2 {
  void f2() {host::member*=2;}
};

Is there a way to do it?

One way that I can think of is to derive p1 and p2 from another class that contains member through virtual inheritance, this makes things compex.

The other is to pass the member to policies as an argument to a function. something like this:

template<class p1, class p2>
struct host : public p1, public p2 {
 double member;
 void hf1() { p1::f1(member);}
 void hf2() { p2::f2(member);}
};
struct p1 {
  void f1(double m) { m+=1;} // this is incorrect but I'm looking for this behavior
};
struct p2 {
  void f2(double m) {m*=2;}
};

Another thought wast to use CRTP and derive both host from policies and policies from host so that the member can be accessed with using but it's not possible.

UPdate (1)

My try with CRTP

template<class p1, class p2>
struct host : public p1, public p2 {
 double member;
};


template<host_type>
struct p1 : public host_type { // error: invalid use of incomplete type 'struct host<p1,p2>'
  void f1() { host_type::member+=1;}
};
template<host_type>
struct p2 : public host_type<p1,p2> { // error: expected template-name before '<' token
  void f2() {host_type::member*=2;}
};
Was it helpful?

Solution

Here's a way to do CRTP without having policies inherit from hosts

template <typename DerivedT>
struct p1
{
    DerivedT&       derived()       { return *static_cast<DerivedT*>(this);       }
    const DerivedT& derived() const { return *static_cast<const DerivedT*>(this); }

    void f1()
    {
        derived().member += 1;
    }
};

template <typename DerivedT>
struct p2
{
    DerivedT&       derived()       { return *static_cast<DerivedT*>(this);       }
    const DerivedT& derived() const { return *static_cast<const DerivedT*>(this); }

    void f2()
    {
        derived().member *= 2;
    }
};

struct host : public p1<host>, public p2<host>
{
     double member;
};
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top