2011-04-28 62 views
1

我创建了一个结构类:C++超载[]操作不

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; 
    } 
    } 
}; 

珠和颗粒是我创造了另一种结构。它的工作原理...感谢

+2

了'结构'是一个类,它可以重载'[]'以及任何类的重载。但是,如果你只需要三个整数,为什么不使用'typedef int a [3]'? – delnan 2011-04-28 14:44:11

回答

1

正如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 
     } 
    } 
}; 
+0

我试过这个,但它返回的结构类型,而不是我想要的。我为我的实际代码编辑了我的消息,没关系我找到了我的错误。 – Yotam 2011-04-28 15:26:02

4

最后一行11.8节(运算符重载,下标)在Stroustrup的 'C++程序设计语言' 的:

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

所以,不,这是不可能的C++。

(尽管当然是struct是C++中的class,但我相信你的意思是你想struct a仍然是一个POD)

+1

只要它不是虚拟的,'a'仍然会是POD,即使有'operator []'。 – 2011-04-28 15:03:44

+0

@Steve:请参阅我的解决方案。我想知道你对此的评论。 – Nawaz 2011-04-28 15:17:46

0

好吧,如果你一定要,你可以解决它与工会,虽然你可在得到皱眉道:

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

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

+0

如果进入特定于实现的领域(使用一个联合的一部分接着另一个联合),我不会感到惊讶,尽管除非编译器做了一些非常糟糕的布局欺骗,否则应该保存。 – delnan 2011-04-28 14:50:54

+0

是的,就像我说的那样,这不是世界上最好的事情,当其他人阅读代码时,最好有一个更好的解释:-)但没有开玩笑,我实际上已经在使用这样的构造次,例如,它像魔术一样在循环中批量加载DLL中的函数指针(例如在编写自己的OpenGL/OpenAL/OpenCL加载器时)。 – Damon 2011-04-28 14:56:14

0

我们假设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; 
     } 
    } 
}; 
+0

Mark ...查看我的解决方案。我想知道你对此的评论。 – Nawaz 2011-04-28 15:13:11

0
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"; 
     } 


}; 
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

+0

似乎是合理的,如果我们不允许修改'a'的定义,尽管我可能会使用'int *'数组而不是矢量。根据预期用途,您可能希望将其赋值为可赋值的(所以要么使用指针而不是对's'的引用,以便它是可重新引用的引用,否则实现副本'operator ='以复制到底层结构体,无论哪个你想要的语义)。 – 2011-04-28 16:07:24

+0

@Steve:我意识到我甚至不需要'int *'。我的更新版本似乎比以前更好。你有什么意见? – Nawaz 2011-04-28 16:48:57