## 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?

13条回答

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.

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

if all your elements are of the same type:

``````for (int i = 0; i < sizeof(rect) / sizeof(rect.x) ; ++i) {
}
``````

with `do_something` expecting a pointer to `int`

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.

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.

horrific hack

``````int *arr = (int*)&my_rect;
for (int i = 0; i < sizeof(rect)/sizeof(int); i++)
{
arr[i] *= factor;
}
``````