【问题标题】:C++ Define an RValue property in a classC++ 在类中定义 RValue 属性
【发布时间】:2016-05-03 00:18:36
【问题描述】:

我有一个带有值的向量:

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 的值从索引3 更改为6

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

【问题讨论】:

  • 实现一元减号运算符:stackoverflow.com/questions/2155275/…
  • @Pierre 我正在寻找一个通用的解决方案。 obj.myvec={0.7,-0.1,0.8} 怎么样?
  • @Pierre 赋值运算符在 myvecB 类上?
  • 使用用户定义的operator -&gt;,你应该可以做到obj-&gt;myvec=-obj-&gt;myvec;
  • @Jarod42, test.cpp:33:6: error: base operand of ‘-&gt;’ has non-pointer type ‘B’

标签: c++ c++11 properties armadillo rvalue


【解决方案1】:

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

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

【讨论】:

  • @ar2015:我没有arma::vec::fixed&lt;10&gt;,但你可以安排我的样本与data.subvec(3,5)一起工作。
  • @ar2015:添加了代码。 wrapperB 是具有您想要的接口的结构。 B::operator -&gt; 应该返回带有正确数据的包装器。注意如果subvec 按值返回(例如代理),您必须删除对PQR 的引用。
  • @ar2015: 缺少 wrapperB 的构造函数,据我了解,它采用了 3 个引用。
  • 是的,(而且你在使用 C++11 吗?否则你也必须在构造中明确:return wrapperB(data.subvec(0,2), data.subvec(3,5), data.subvec(6,9));
  • 非常感谢。由于在像obj-&gt;Q 这样的每次调用中,其他子向量都是通过wrapperB(data.subvec(0,2), data.subvec(3,5), data.subvec(6,9)) 计算的,性能如何?编译器会为它们生成更多的汇编代码吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-28
  • 2014-09-29
  • 2015-03-24
  • 1970-01-01
  • 2011-01-22
相关资源
最近更新 更多