c++重载没有类的[]操作符

c++ overloading the [] operator without a class

本文关键字:操作符 重载 c++      更新时间:2023-10-16

我已经创建了一个结构:

struct a{
   int a1;
   int a2;
   int a3;
};

是否有办法创建一个函数,其中a[1]将以相同的方式访问a1,我将能够通过数组?

编辑,我已经粘贴了我实际做的部分:
struct lipid{
  particle mainPart;
  bead * head;
  bead * body;
  bead * tail;
  vec direction;
  bead * operator[](int index){
    switch(index){
    case 0: return head;
    case 1: return body;
    case 2: return tail;
    default: return body;
    }
  }
};

head和particle是我创建的另一个结构体。它的工作原理……由于

Stroustrup的《c++编程语言》第11.8节(操作符重载,下标)的最后一行:

 'An operator []() must be a member function.'

所以,这在c++中是不可能的。

(虽然当然struct是c++中的class,但我假设您的意思是您希望struct a保持POD)

正如delnan所指出的,你可以在结构体上使用方法,就像在类上一样。

:

struct a{
   int a1;
   int a2;
   int a3;
   int &operator[]( int i ){ 
       switch(i){
       case 1: return a1;
       case 2: return a2;
       case 3: return a3;
       default: return -1
       }
   }
};

由于operator [] must be a member function,正如其他人所指出的,您不能这样做。

但是我想出了下面的包装器类subscriptable,它可以帮助你模拟它:

class subscriptable
{
  A & a;
  public:
    subscriptable(A & a) : a(a) {}
    subscriptable(const subscriptable & s) : a(s.a) {}
    int & operator[](int i)
    { 
       if ( i < 0 || i > 2 ) throw "index out of range";
       else if ( i == 0 ) return a.a1;
       else if ( i == 1 ) return a.a2;
       else return a.a3;
    }
    operator A & () { return a; }
};
void print(A & a)
{
   subscriptable s = a; //a implicitly converts to subscriptable
   for ( int i = 0 ; i < 3 ; i++ ) 
       std::cout << s[i] << std::endl;
}
int main() 
{
        A a;
        subscriptable s = a; //a implicitly converts to subscriptable
        for ( int i = 0 ; i < 3 ; i++ ) 
             s[i] = (i + 1) * 100;
        print(s); //s implicitly converts to A
        return 0;
}
输出:

100
200
300

在线演示:http://www.ideone.com/ymmg1

好吧,如果你必须,你可以用一个联合来解决它,尽管你可能会不赞成:

union
{
    struct
    {
        int a1;
        int a2;
        int a3;
    };
    int a[]; // may need compiler-specific tweaking
};

请注意,并非所有编译器都支持int a[],您可能必须编写int a[0]甚至int a[3],这取决于编译器/语言方言。

让我们假设struct a在某个库中,您无法更改它,否则您将采取@delnan的typedef建议(typedef int a[3])。

如果结构不是以多态方式使用,你可能会滥用继承并自己添加操作符:

struct a_with_brackets : public a
{
    int& operator[](int index)
    {
        switch(index)
        {
        case 1 : return a1;
        case 2 : return a2;
        case 3 : return a3;
        }
    }
};
struct a{
   int a1;
   int a2;
   int a3;
   int & operator[]( int i ) {
      if ( i == 0 ) {
         return a1;
      }
      else if ( i == 1 ) {
         return a2;
      }
      else if ( i == 2 ) {
         return a3;
      }
      else {
         throw "index error";
      }

};