Предположим, у меня есть хост-класс, который содержит член:
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;}
};
Вот способ сделать 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;
};
Других решений пока нет …