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
即从索引 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;
}
使用用户定义的 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}; }
};
所以在你的情况下,代码可能是这样的:
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)};
}
};
我有一个向量,其值为:
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;
}
使用用户定义的 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}; }
};
所以在你的情况下,代码可能是这样的:
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)};
}
};