Копирование данных между смешанными типами

У меня есть несколько разных типов данных, которые я хочу иметь возможность добавлять к объекту (здесь они называются «A» и «B»). Если я добавлю их в одном и том же порядке для двух разных объектов, копирование одного в другой будет работать нормально (например, A<B<Point> > abPoint1; A<B<Point> > abPoint2 = abPoint1;). Однако, если я добавлю их в разных порядках (например, A<B<Point> > abPoint; B<A<Point> > baPoint = abPoint; // compiler error) потому что тип подписи не совпадает. Есть ли способ сделать это без явной обработки экспоненциального числа миксиновых комбинаций?

Вот MWE для тестирования:

// Standard point representation
struct Point
{
double x,y,z;
};

// A mixin to add an 'A' value to a point
template<class Base>
class A : public Base
{
public:

double a;
};

// A mixin to add an 'B' value to a point
template<class Base>
class B : public Base
{
public:

double b;
};

int main()
{
A<Point> aPoint;

B<Point> bPoint;

// A<Point> a2Point = bPoint; // obviously we can't do this

A<B<Point> > abPoint;
B<A<Point> > baPoint;

abPoint = baPoint; // Something like this seems like it should be possible

return 0;
}

И даже лучше, есть ли способ копировать только «доступные» фрагменты данных? То есть:

A<B<C<D<Point>>>> abcdPoint;
A<C<Point>> acPoint;
abcdPoint = acPoint;

будет только копировать членов из А и С.

3

Решение

Чтобы иметь возможность показать, что я думаю, ответ будет без реального тестирования, чтобы увидеть, работает ли он, я назову это ответом.

template<class BASE>
class A {
public:
A<BASE> operator=(const &A<BASE> right) {
// does not block all errors, but catches some:
static_assert( std::is_base_of< A, BASE >::value, "CRTP failure" );
auto* dis = static_cast<BASE*>(this);
BASE::operator=(right);
dis->a = right.a;
return this;
}
double a;
};

template<class BASE>
class B {
public:
B<BASE> operator=(const &B<BASE> right) {
// does not block all errors, but catches some:
static_assert( std::is_base_of< B, BASE >::value, "CRTP failure" );
auto* dis = static_cast<BASE*>(this);
dis->b = right.b;
BASE::operator=(right);
return this;
}
double b;
};class aPoint: public A<aPoint>, Point {};

class bPoint: public B<bPoint>, Point {};

class abPoint: public B < A<abPoint> > {};

class baPoint: public A < B<baPoint> > {};
0

Другие решения

Я привел в пример ваш пример. Копирование abPoint в baPoint работает.

#include <iostream>

struct Point
{
public:
double x,y,z;
};

// A mixin to add an 'A' value to a point
template<class Base>
class A : public Base
{
public:
A& operator=( const Point& rhs )
{
Point::operator=(rhs);
return *this;
}

template <typename T_RHS>
A& operator=( const T_RHS& rhs )
{
Base::operator=(rhs);
a = rhs.a;
return *this;
}

double a;
};

// A mixin to add an 'B' value to a point
template<class Base>
class B : public Base
{
public:
B& operator=( const Point& rhs )
{
Point::operator=(rhs);
return *this;
}

template <typename T_RHS>
B& operator=( const T_RHS& rhs )
{
Base::operator=(rhs);
b = rhs.b;
return *this;
}

double b;
};

int main()
{
Point point;

A<Point> aPoint;
aPoint = point;

B<Point> bPoint;
bPoint = point;

B< A<Point> > baPoint;
A< B<Point> > abPoint;
abPoint = baPoint;

// Fails
//aPoint = bPoint;
//bPoint = aPoint;

// This works
aPoint.Point::operator=(bPoint);
bPoint.Point::operator=(aPoint);

return 0;
}
0

По вопросам рекламы [email protected]