Is there a way of applying a function to each memb

2020-03-21 02:02发布

You have a simple struct, say:

typedef struct rect
{
    int x;
    int y;
    int width;
    int height;
}
rect;

And you want to multiply each element by a factor. Is there a more concise way of performing this operation, other than multiplying each member by the value?

标签: c++
13条回答
地球回转人心会变
2楼-- · 2020-03-21 02:40

There are some issues associated with inheriting from standard classes; but if you're willing to accept those issues, you can do something analagous to what others have suggested, but using std::valarray instead. It would look something like:

#include <valarray>

class rect : public std::valarray<int>
{
  public:
    rect() : std::valarray(4, 0) {}

    int& x() { return (*this)[0]; }
    int& y() { return (*this)[1]; }
    int& width() { return (*this)[2]; }
    int& height() { return (*this)[3]; }
};

With this, you inherit the vector operations defined on std::valarray<int>.

I wouldn't necessarily recommend this approach. I merely suggest that it can be done.

查看更多
Deceive 欺骗
3楼-- · 2020-03-21 02:42

If all are the same type, use a union combined with an anonymous struct, inside of your struct:

struct MyStruct {
  union {
    int data[4];
    struct {
      int x,y,z,w;
    }
  };
};

then:

MyStruct my_struct;
cout << my_struct.x << my_struct.y << my_struct.z << my_struct.w;
for (size_t i = 0; i < 4; ++i)
  some_function(my_struct.data[i]); // access the data via "data" member
cout << my_struct.x << my_struct.y << my_struct.z << my_struct.w; // voila!, stryct data has changed!

If youre using different types have a look at boost::fusion

查看更多
淡お忘
4楼-- · 2020-03-21 02:42

if all your elements are of the same type:

for (int i = 0; i < sizeof(rect) / sizeof(rect.x) ; ++i) {
    do_something(reinterpret_cast<int *>(adress_of_your_struct) + i);
}

with do_something expecting a pointer to int

查看更多
老娘就宠你
5楼-- · 2020-03-21 02:45

Boost.Fusion offers the BOOST_FUSION_ADAPT_STRUCT macro, which can turn any struct into a Fusion sequence, which Fusion can then iterate over (as demoed in the Quick Start).

Another option is to use a third-party C++ reflection library like Reflex to iterate over a struct's members.

However, all of this may be overkill for your purposes; manually listing each of the class's members may be less elegant, but it's much simpler, and simplicity in coding is important.

查看更多
虎瘦雄心在
6楼-- · 2020-03-21 02:47

Not really. Programatically obtaining a list of the elements of a struct requires reflection, which C++ does not support.

Your two options are to just give the struct a method that does this the long-winded way and then use that method in all other places, or to manually mimic reflection, for example by giving the struct another element which is an array of pointers to all of its other elements (built within the struct's constructor), and then looping over that to perform the scaling function.

查看更多
淡お忘
7楼-- · 2020-03-21 02:48

horrific hack

int *arr = (int*)&my_rect;
for (int i = 0; i < sizeof(rect)/sizeof(int); i++)
{
     arr[i] *= factor;
}
查看更多
登录 后发表回答