一般来说,对于想要使用多参数operator()
而不是operator[]
。
嗯,如果不是很明显,C++中没有operator[][]
。这只是operator[]
申请两次。这意味着如果你想要这个表示法,那么你必须让第一个返回第二个可以应用到的结果(可索引的东西或代理)。
下面的代码勾勒一些方法,选择你喜欢的东西:
#include <iostream>
#include <vector>
template< int n >
int& dummy() { static int elem = n; return elem; }
struct Mat1
{
int operator() (int const x, int const y) const
{ return dummy<1>(); }
int& operator() (int const x, int const y)
{ return dummy<1>(); }
Mat1(int, int) {}
};
struct Mat2
{
int at(int const x, int const y) const
{ return dummy<2>(); }
int& at(int const x, int const y)
{ return dummy<2>(); }
Mat2(int, int) {}
};
struct Mat3
{
struct At { At(int x, int y) {} };
int operator[](At const i) const
{ return dummy<3>(); }
int& operator[](At const i)
{ return dummy<3>(); }
Mat3(int, int) {}
};
class Mat4
{
protected:
int get(int const x, int const y) const
{ return dummy<4>(); }
void set(int const x, int const y, int const v) {}
class AssignmentProxy
{
private:
Mat4* pMat_;
int x_;
int y_;
public:
void operator=(int const v) const
{ pMat_->set(x_, y_, v); }
int value() const { return pMat_->get(x_, y_); }
operator int() const { return value(); }
AssignmentProxy(Mat4& mat, int const x, int const y)
: pMat_(&mat), x_(x), y_(y)
{}
};
public:
int operator()(int const x, int const y) const
{ return get(x, y); }
AssignmentProxy operator()(int const x, int const y)
{ return AssignmentProxy(*this, x, y); }
Mat4(int, int) {}
};
class Mat5
{
protected:
int at(int const x, int const y) const
{ return dummy<4>(); }
int& at(int const x, int const y)
{ return dummy<5>(); }
class RowReadAccess
{
private:
Mat5 const* pMat_;
int y_;
public:
int operator[](int const x) const
{
return pMat_->at(x, y_);
}
RowReadAccess(Mat5 const& m, int const y)
: pMat_(&m), y_(y)
{}
};
class RowRWAccess
{
private:
Mat5* pMat_;
int y_;
public:
int operator[](int const x) const
{
return pMat_->at(x, y_);
}
int& operator[](int const x)
{
return pMat_->at(x, y_);
}
RowRWAccess(Mat5& m, int const y)
: pMat_(&m), y_(y)
{}
};
public:
RowReadAccess operator[](int const y) const
{ return RowReadAccess(*this, y); }
RowRWAccess operator[](int const y)
{ return RowRWAccess(*this, y); }
Mat5(int, int) {}
};
struct Mat6
{
private:
std::vector<int> elems_;
int width_;
int height_;
int indexFor(int const x, int const y) const
{
return y*width_ + x;
}
public:
int const* operator[](int const y) const
{
return &elems_[indexFor(0, y)];
}
int* operator[](int const y)
{
return &elems_[indexFor(0, y)];
}
Mat6(int const w, int const h)
: elems_(w*h, 6), width_(w), height_(h)
{}
};
int main()
{
using namespace std;
enum{ w = 1024, h = 1024 };
typedef Mat3::At At;
Mat1 m1(w, h);
Mat2 m2(w, h);
Mat3 m3(w, h);
Mat4 m4(w, h);
Mat5 m5(w, h);
Mat6 m6(w, h);
wcout
<< m1(100, 200) // No fuss simple, but exposes element ref.
<< m2.at(100, 200) // For those who don't like operators.
<< m3[At(100, 200)] // If you really want square brackets mnemonic.
<< m4(100, 200) // Hides element ref by using assignment proxy.
<< m5[200][100] // Ditto but with square brackets (more complex).
<< m6[200][100] // The minimum fuss square brackets, exposes elem ref.
<< endl;
}
哦我张贴的代码,我还没有完全隐藏在内部存储Mat5
后发现:它需要一个额外的代理水平,如Mat4
。所以这种方法非常复杂。我不会这样做(Mat1
是我认为的很好很容易),但有些人认为proxys很酷,数据隐藏更加酷&hellip;
总结一下,没有“ ”正确的方法来重载operator[]
。有很多方法(如上面的代码所示),每个方法都有一些权衡。一般而言,’使用operator()
会更好,因为与operator[]
相比,它可以使用任意数量的参数。
如果你可以处理矩阵(x,y)的语法,那就去吧。我们的代码库无法使用,因为我们希望能够使用二维数组快速交换旧代码,而不是使用我们的矩阵类。是牺牲了一些安全,但很快的一种方式达到你想要的是要做到: const的真实*运算符[](INT行)const的 { 返回_data [行]。 }; 但是,这会牺牲在获取列时对结果执行边界检查的功能,因此可以使用代理对象代替更安全的结果。 – stinky472
我真的希望能够交换我的代码与GLM代码,只需通过改变使用的命名空间,所以我不能与运营商去()。 – fishfood