mardi 26 janvier 2016

C++ Define an RValue property in a class

I have a vector with value:

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

and I need to change the values of the sub-vector from index 3 to 6;

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

The following code works:

#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)
    {
    }

};

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

    // ok:
    obj.data.subvec(3,5)=-obj.data.subvec(3,5);

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

    return 0;
}

Result:

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

Now, if I want to put the data.subvec(3,5) inside the class so I can call it from any other function without worrying about index updating.

obj.myvec=...

Also, I expect size of obj does not increase even by 1 byte.

So, I wrote the following code:

#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(3,5))&& myvec()
    {
        return data.subvec(3,5);
    }
};

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

    // ok:
    // obj.data.subvec(3,5)=-obj.data.subvec(3,5);

    // run time error:
    // error: copy into submatrix: incompatible matrix dimensions: 4206014x140729784176176 and 4206014x1
    // terminate called after throwing an instance of 'std::logic_error'
    //   what():  copy into submatrix: incompatible matrix dimensions: 4206014x140729784176176 and 4206014x1
    // Aborted (core dumped)
    obj.myvec()=-obj.myvec();

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

    return 0;
}


This code has three problems:

1- the subvector myvector needs parenthesis fro being called (myvector() instead of myvector)

2- the following warning:

test.cpp:20:25: warning: returning reference to temporary [-Wreturn-local-addr]
   return data.subvec(3,5);
                         ^

3- even after running the code, I get this runtime error:

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

error: copy into submatrix: incompatible matrix dimensions: 4206014x140720661107248 and 4206014x1

terminate called after throwing an instance of 'std::logic_error'
  what():  copy into submatrix: incompatible matrix dimensions: 4206014x140720661107248 and 4206014x1
Aborted (core dumped)

How to fix them?

Aucun commentaire:

Enregistrer un commentaire