用于多个数组/向量的重载索引操作符
C++ Overload index operator for more than one array/vector
我不是高级程序员。我如何重载[]
操作符的类,有两个(或更多)数组/矢量类型变量?
class X
{
protected:
std::vector<double> m_x, m_y;
public:
double& operator[](const short &i) { return ???; }
};
我应该为???
使用什么,或者我如何做到这一点(可能添加其他定义?)以便能够调用任何一个变量?
附加问题:这是否允许class derived : public X
类型的其他类访问m_x
和m_y
进行写入?
更新:
谢谢每个人的回答,但我担心如果我划清界限,那么我的第一个问题的答案是否定的,第二个问题的答案是肯定的。较长的版本意味着一个额外的struct
,或class
,或普通的setter/getter,我想通过使用一个简单的函数来避免这一切。
目前的解决方案是对每个类中的每个变量的(临时)引用,以避免额外的X::
类型(并保持代码清晰),因为m_x
将以某种方式存在。
您可以为此编写一个函数,如:
double &get(unsigned int whichVector, unsigned int index)
{
return (whichVector == 0 ? m_x[index] : m_y[index]);
}
或使用operator():
struct A
{
std::vector<int> a1;
std::vector<int> a2;
int operator()(int vec, int index)
{
return (vec == 0 ? a1[index] : a2[index]);
}
};
A a;
auto var = a(0, 1);
但是,这仍然有点奇怪:)也许你应该在外面给出一个const ref,比如:
const std::vector<double> &getX() const { return m_x; }
和第二个问题:protected在public继承中将被转换为private (child/derived可以访问这些成员)
假设您希望m_x
和m_y
根据相同的参数和单个返回值进行索引:
struct XGetter
{
double& x;
double& y;
};
XGetter operator[](const short &i) { return { m_x[i], m_y[i] }; }
和const
过载:
struct XGetterReadOnly
{
double x;
double y;
};
XGetterReadOnly operator[](const short &i) const { return { m_x[i], m_y[i] }; }
编译器将在适当的地方优化掉中间类XGetter
和XGetterReadOnly
,如果你是c++的新手,这可能很难让你明白。
如果使用mixin不让你感到不舒服,你可以使用这样的标签调度:
#include <utility>
#include <vector>
#include <iostream>
template <size_t I>
struct IndexedVector {
std::vector<double> v;
IndexedVector():v(10){}
};
template <size_t I>
struct tag {
int i;
};
template <size_t S, class = std::make_index_sequence<S>>
struct MixinVector;
template <size_t S, size_t... Is>
struct MixinVector<S, std::index_sequence<Is...>>: IndexedVector<Is>... {
template <size_t I>
double &operator[](tag<I> i) {
return IndexedVector<I>::v[i.i];
}
};
int main() {
MixinVector<2> mv;
mv[tag<0>{0}] = 1.0;
std::cout << mv[tag<0>{0}] << std::endl;
}
要使用std::index_sequence
,你需要编译器支持c++14(你可以在c++11中实现它)。通过简单的MixinVector
模板参数修改,该方法可以很容易地扩展到任意数量的向量。
无论是在概念层面还是在设计层面,都存在很多问题。
你能同时用手指指着两个不同的东西吗?没有?这就是为什么你不能用一个索引来处理两个不同的向量,以保持它们的区别。
你可以做很多事情:任何将两个值"组合"成一个值的方法都是好的从语法的角度来看:
return m_x[i]+m_y[x]
或return sin(m_x[i])*cos(m_y[i])
或return whatever_complicated_expression_you_like_much
但这是什么意思?问题是为什么在你的课堂上有两个向量?你想让他们代表什么?(语义上)索引它们是什么意思?
我可以做的是保持它们的区别
auto operator[](int i) const
{ return std::make_pair(m_x[i],m_y[i]); }
得到一个std::pair<double,double>
,它的fist
和second
成员分别是m_x[i]和m_y[i]。
还是……你可以return std::vector<double>{m_x[i],m_y[i]};
关于你的另一个问题:是的,继承为public使新类能够访问受保护的部分:这就是protected的作用。
是的,你可以R/W: public,protected和private是关于可见性的,而不是可读性和可写性。这就是const的作用
但是:你的类代表什么?没有这些信息,我们就不能确定什么有意义,什么没有意义。
好的,说明你的评论:
需要两个不同的函数:一个用于读(double operator[](unsigned) const
),一个用于写(double& operator[](unsigned) const
)
如果你知道向量有一个已知的长度,比如200,你可以编写一个像i/1000这样的索引转换来识别向量,i%1000来获得索引,所以0..199是第一个,1000…2000年第二次……地址是第三……等。
还是……您可以使用std::pair<unsigned,unsigend>
作为索引(like operator[](const std::pair<unsigned,unsigned>& i)
),使用i.first来识别向量,i.second来索引它,然后调用x[{1,10}], x[{3,30}]等。
还是……你可以用
把向量链在一起if(i<m_x.size()) return m_x[i]; i-=m_x:size();
if(i<m_y.size()) return m_y[i]; i-=m_y:size();
if(i<m_z.size()) return m_z[i]; i-=m_z:size();
...
以便连续索引它们。
但是你可以使用向量数组而不是不同的向量变量得到更多的算法解
如果你有std::array<std::vector<double>,N> m;
而不是m_x, m_y和m_z,上面的代码可以…
for(auto& v: m)
{
if(i<v.size()) return v[i];
i-=v.size();
}
可以返回有两个double的struct
struct A{
double& x;
double& y;
A(A& r) : x(r.x), y(r.y){}
A(double& x, double& y) : x(x), y(y){}
};
class X
{
protected:
std::vector<double> m_x, m_y;
public:
A operator[](const short &i) {
A result(m_x[i], m_y[i]);
return result;
}
};
感谢编辑@marcinj
- 继承函数的重载解析
- 数组索引的值没有增加
- 你能重载对象变量名本身返回的内容吗
- 从父命名空间重载类型
- 重载元组索引运算符-C++
- 数组索引重载错误
- 重载运算符 [] 用于从对象数组中给出特定索引
- 在对象上运行,运算符重载 () 与索引
- C []索引操作员重载作为登录器和突变器
- C++指向重载索引的箭头 ( this->[ ] )
- 数组索引运算符重载.现在无法使用比较运算符
- 是否可以使用运算符重载按索引分配用户定义的数组?-C++
- 继承自 std::vector<T> 和重载运算符 [] 用于自定义索引
- c++为对象赋值重载数组索引运算符
- 重载枚举索引数组的std::get
- 重载c++下标[]操作符,可以使用长int索引
- 用于多个数组/向量的重载索引操作符
- 是否可以重载索引操作符[]以从整数返回位?
- 是否重载索引运算符以模拟POD多维数组
- 如何重载子索引操作符,使其在获取项和设置项时表现不同