Как разделить участника между политиками?

Предположим, у меня есть хост-класс, который содержит член:

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

и я хочу использовать один и тот же член в p1 и 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;}
};

Есть ли способ сделать это?

Один из способов, который я могу придумать, - это получить p1 а также p2 из другого класса, который содержит член посредством виртуального наследования, это делает вещи более привлекательными.

Другой - передать член в политику в качестве аргумента функции. что-то вроде этого:

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;}
};

Другая мысль заключалась в том, чтобы использовать CRTP и извлекать хост из политик, а политики из хоста, чтобы к члену можно было получить доступ с помощью using но это невозможно

ОБНОВЛЕНИЕ (1)

Моя попытка с 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;}
};

1 ответ

Решение

Вот способ сделать CRTP, не наследуя политики от хостов

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;
};
Другие вопросы по тегам