C++ 在 class 中定义 RValue 属性

C++ Define an RValue property in a class

我有一个向量,其值为:

obj={1.0,2.0,3.0, 4.0,5.0,6.0 ,7.0,8.0,9.0,10.0}

假设,数学上 obj 被划分为三个子向量:

obj={P, Q , R}

其中 P={1.0,2.0,3.0}Q={4.0,5.0,6.0}R={7.0,8.0,9.0,10.0}

我需要更改子向量的值 Q 即从索引 36;

obj={1.0,2.0,3.0, -4.0,-5.0,-6.0 ,7.0,8.0,9.0,10.0}

不仅否定,而且我希望能够在obj的子向量上独立地做任何其他动作。

以下代码有效:

#include <armadillo>
#include <iostream>

using namespace std;

typedef arma::vec::fixed<10> x_vec;

class B
{
public:
    x_vec data;

    B(x_vec init) :
        data(init)
    {
    }

    inline decltype(data.subvec(0,2)) P()
    {
        return data.subvec(0,2);
    }

    inline decltype(data.subvec(3,5)) Q()
    {
        return data.subvec(3,5);
    }

    inline decltype(data.subvec(6,9)) R()
    {
        return data.subvec(6,9);
    }

};

int main()
{
    B obj({1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0});
    cout<<"sizeof obj.data: "<<sizeof(obj.data)<<endl;
    cout<<"sizeof obj: "<<sizeof(obj)<<endl;
    cout<<"value of obj:"<<endl;
    obj.data.print();

    obj.Q()=-obj.Q();

    cout<<"value of obj:"<<endl;
    obj.data.print();

    return 0;
}

结果

sizeof obj.data: 192
sizeof obj: 192
value of obj:
    1.0000
    2.0000
    3.0000
    4.0000
    5.0000
    6.0000
    7.0000
    8.0000
    9.0000
   10.0000
value of obj:
    1.0000
    2.0000
    3.0000
   -4.0000
   -5.0000
   -6.0000
    7.0000
    8.0000
    9.0000
   10.0000

但是,如何让它在 属性 上不带括号工作?

我的意思是使用

obj.Q=-obj.Q;

而不是

obj.Q()=-obj.Q();

我也不想增加 obj 的大小。

此外,我正在寻找通用解决方案。不是仅否定我的向量的子向量的解决方案。


更新

最终代码有效:

#include <armadillo>
#include <iostream>

using namespace std;

typedef arma::vec::fixed<10> x_vec;

struct wrapperB
{
    wrapperB* operator ->() { return this; }

    typedef decltype(std::declval<x_vec>().subvec(0, 2)) P_type;
    typedef decltype(std::declval<x_vec>().subvec(3, 5)) Q_type;
    typedef decltype(std::declval<x_vec>().subvec(6, 9)) R_type;

    P_type& P;
    Q_type& Q;
    R_type& R;

    wrapperB(P_type _p,Q_type _q,R_type _r) :
        P(_p), Q(_q), R(_r)
    {
    }
};

class B
{
public:
    x_vec data;

    B(x_vec init) : data(init) {}

    wrapperB operator -> ()
    {
        return wrapperB(data.subvec(0,2), data.subvec(3,5), data.subvec(6,9));
    }
};

int main()
{
    B obj({1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0});
    cout<<"sizeof obj.data: "<<sizeof(obj.data)<<endl;
    cout<<"sizeof obj: "<<sizeof(obj)<<endl;
    cout<<"value of obj:"<<endl;
    obj.data.print();

    obj->Q=-obj->Q;

    cout<<"value of obj:"<<endl;
    obj.data.print();

    return 0;
}

使用用户定义的 operator ->,您可能会滥用它来拥有

obj->myvec=-obj->myvec;

例如:

template <typename T>
struct wrapper
{
    wrapper<T>* operator ->() { return this; }

    std::vector<T>& myvec;
};

template <typename T>
class B
{
public:
    std::vector<T> data;

    B(const std::vector<T>& init) : data(init) {}

    wrapper<T> operator -> () { return {data}; }

};

Demo

所以在你的情况下,代码可能是这样的:

struct wrapperB
{
    wrapperB* operator ->() { return this; }

    decltype(std::declval<x_vec>().subvec(0, 2))& P;
    decltype(std::declval<x_vec>().subvec(3, 5))& Q;
    decltype(std::declval<x_vec>().subvec(6, 9))& R;
};

class B
{
public:
    x_vec data;

    B(x_vec init) : data(init) {}

    wrapperB operator -> ()
    {
        return {data.subvec(0,2), data.subvec(3,5), data.subvec(6,9)};
    }
};