Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在mixin类型之间复制数据_C++_Mixins - Fatal编程技术网

C++ 在mixin类型之间复制数据

C++ 在mixin类型之间复制数据,c++,mixins,C++,Mixins,我希望能够将一些不同类型的数据添加到对象中(这里称为“A”和“B”)。如果我为两个不同的对象以相同的顺序添加它们,那么将一个对象复制到另一个对象就可以了(例如,A abPoint1;A abPoint2=abPoint1;)。但是,如果我以不同的顺序添加它们(例如,A abPoint;B baPoint=abPoint;//编译器错误),因为类型签名不同。有没有办法在不显式处理指数数量的mixin组合的情况下做到这一点 以下是用于测试的MWE: // Standard point represe

我希望能够将一些不同类型的数据添加到对象中(这里称为“A”和“B”)。如果我为两个不同的对象以相同的顺序添加它们,那么将一个对象复制到另一个对象就可以了(例如,
A abPoint1;A abPoint2=abPoint1;
)。但是,如果我以不同的顺序添加它们(例如,
A abPoint;B baPoint=abPoint;//编译器错误
),因为类型签名不同。有没有办法在不显式处理指数数量的mixin组合的情况下做到这一点

以下是用于测试的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;
}
//标准点表示法
结构点
{
双x,y,z;
};
//向点添加“A”值的混合
模板
A类:公共基地
{
公众:
双a;
};
//向点添加“B”值的混合
模板
B类:公共基地
{
公众:
双b;
};
int main()
{
一个点;
B点;
//A a2Point=b点;//显然我们不能这样做
A点;
B点;
abPoint=baPoint;//像这样的事情似乎应该是可能的
返回0;
}
更好的是,是否有一种方法可以只复制“可用”的数据片段?即:

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

我只会复制A和C中的成员。

为了能够显示我认为答案是什么,而不需要真正测试它是否有效,我将称之为答案

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> > {};
模板
甲级{
公众:
A运算符=(常数&右侧){
//不会阻止所有错误,但会捕获一些错误:
静态断言(std::is_base_of::值,“CRTP故障”);
自动*dis=静态_转换(此);
BASE::operator=(右);
dis->a=右侧。a;
归还这个;
}
双a;
};
模板
B类{
公众:
B运算符=(常量和B右侧){
//不会阻止所有错误,但会捕获一些错误:
静态断言(std::is_base_of::值,“CRTP故障”);
自动*dis=静态_转换(此);
dis->b=右侧。b;
BASE::operator=(右);
归还这个;
}
双b;
};
类点:公共A点{};
类B点:公共B点{};
类abPoint:public B{};
类B点:公共A{};

我尽我所能充实了你的例子。将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;
}
#包括
结构点
{
公众:
双x,y,z;
};
//向点添加“A”值的混合
模板
A类:公共基地
{
公众:
A运算符=(常量点和rhs)
{
点::运算符=(rhs);
归还*这个;
}
模板
A和运算符=(常数T_RHS和RHS)
{
基::运算符=(rhs);
a=rhs.a;
归还*这个;
}
双a;
};
//向点添加“B”值的混合
模板
B类:公共基地
{
公众:
B和运算符=(常数点和rhs)
{
点::运算符=(rhs);
归还*这个;
}
模板
B和运算符=(常数T_RHS和RHS)
{
基::运算符=(rhs);
b=rhs.b;
归还*这个;
}
双b;
};
int main()
{
点-点;
一个点;
aPoint=点;
B点;
B点=点;
BB点;
AabPoint;
abPoint=baPoint;
//失败
//aPoint=b点;
//b点=a点;
//这很有效
aPoint.Point::operator=(bPoint);
点::运算符=(aPoint);
返回0;
}

。参考CRTP的这个问题的答案可能会对您有所帮助。它将允许您重铸“this”和其他参数,以测试它们是否具有所需的数据,并编写一个运算符=来执行该操作。嗯,我不确定我是否遵循了这一点。所以这里我需要模板点?那么我应该为哪个类编写运算符=?每个人都会复制他们自己的数据吗(他们会自动称为“递归的”?)?嗯。。假设你有一个C类:带有成员变量double a的公共基;然后你做到了——一点;C点;cPoint=aPoint@KorreyD不太一样——它实际上比这个更强。如果我有一个acPoint和一个aPoint,我希望acPoint=aPoint复制A类中的所有内容,因为这是它们唯一的共同点。同样,acPoint=point只会复制point的成员。但它需要扩展,就像一个abcdPoint;A点;abcdPoint=acPoint只从A和C复制成员。明白我的意思吗?我在问题中添加了这个描述,因为这才是我真正想要的。在我尝试一个更复杂的例子之前,这不应该起作用吗?我得到了“从点到非标量类型A的转换请求”-这不是模板赋值运算符应该处理的吗?您需要在运算符=。因为除非a(或b)在右边存在,否则它不会编译,所以它可能会工作。在这个要点中,我有意不复制operator=中的“a”,这样它只会从点复制数据。但似乎没有使用模板运算符,而是使用默认运算符=?此代码->A aPoint=点;调用复制构造函数(因为aPoint同时被声明和赋值)。您在代码中覆盖的是复制赋值运算符。所以如果你想让它击中你想做的那段代码:一个aPoint;aPoint=点@KorreyD啊,当然,谢谢。回到更难的情况。。。哈维德,知道为什么普通赋值运算符失败了吗?这就解决了排序问题(AB vs BA),但如果存在不同的混合子集(例如AC vs AB),它看起来就不起作用了-也就是说,AC将尝试从传入的任何东西(AB)复制C,而这将失败,对吗?rhs的类型是错误的。我的猜测是,如果将rhs投射到某个点,正常=将起作用。