开发者

What does this C++ syntax mean and why does it work?

开发者 https://www.devze.com 2023-01-14 01:39 出处:网络
I was looking through the source of OpenDE and I came across some wierd syntax usage of the array indexing operator \'[]\' on a class. Here\'s a simplified example to show the syntax:

I was looking through the source of OpenDE and I came across some wierd syntax usage of the array indexing operator '[]' on a class. Here's a simplified example to show the syntax:

#include <iostream>

class Point
{
public:
    Point() : x(2.8), y(4.2), z(9.5) {}

    operator const float *() const
    {
        return &x;
    }

private:
    float x, y, z;
};

int main()
{
    Point p;
    std::cout << "x: " << p[0] << '\n'
              << "y: " << p[1] << '\n'
              << "z: " << p[2];
}

Output:开发者_开发知识库

x: 2.8
y: 4.2
z: 9.5

What's going on here? Why does this syntax work? The Point class contains no overloaded operator [] and here this code is trying to do an automatic conversion to float somewhere.

I've never seen this kind of usage before -- it definitely looks unusual and surprising to say the least.

Thanks


p is being converted implicitly into a const float* const, which points to x. So *p is x, *(p+1) is y, and so on. It's a pretty weird idea (and confusing!) to do it this way, of course. It's usually preferable to store x, y, and z in an array and have a function to get the entire array if they really want to do things this way.


The idea here is to give access to the members of the Point by either subscript or name. If you want to do that, however, you'd be better off overloading operator[] something like this:

struct Point { 
    float x, y, z;

    float &operator[](size_t subscript) { 
        switch(subscript) {
            case 0: return x;
            case 1: return y;
            case 2: return z;
            default:  throw std::range_error("bad subscript");
        }
    }
};

This way, if the compiler inserts padding between the floats, it will still work -- and anybody who can read C++ should be able to understand it without any problems.


This is just a way of treating your member data as an array. You can also do this with structs. This is useful when you want readability, yet want to be able to iterate over simple data structures. An example use would be to declare a matrix this way:

typedef struct {
   CGFloat m11,m12,m13,m14;
   CGFloat m21,m22,m23,m24;
   CGFloat m31,m32,m33,m34;
   CGFloat m41,m42,m43,m44;
} CATransform3D;

You can conveniently reference each cell by name, yet you can also pass around a pointer to m11 everywhere (and C will see your struct as an array, m11 being the first element), and iterate over all the elements.

0

精彩评论

暂无评论...
验证码 换一张
取 消