Is there a way to apply a function to each member of a structure in C ++?

You have a simple structure, 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 to perform this operation besides multiplying each element by a value?

+5
source share
13 answers

Not really. Getting a list of structure elements programmatically requires reflection, which C ++ does not support.

- , , , , , ( ), .

+10

; .

, , , :

struct rect
{
    // actually store the data in an array, not as distinct elements
    int values_[4];

    // use accessor/mutator functions to modify the values; it is often best to
    // provide const-qualified overloads as well.
    int& x()      { return values_[0]; }
    int& y()      { return values_[1]; }
    int& width()  { return values_[2]; }
    int& height() { return values_[3]; }

    void multiply_all_by_two()
    {
        for (int i = 0; i < sizeof(values_) / sizeof(values_[0]); ++i)
            values_[i] *= 2;
    }
};

( , ( x, y, ?), )

+10

Boost.Fusion BOOST_FUSION_ADAPT_STRUCT, Fusion, Fusion ( ).

- ++, ​​ Reflex, .

; , .

+10

128- , SIMD . , Intel Integrated Performance Primitives (IPP) , , .. .

, , .

+5

, :

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

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!

, boost:: fusion

+2

, , , *:

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

rect operator*(const rect& r, int f)
{
  rect ret=r;
  ret.x*=f;
  ret.y*=f;
  ret.width*=f;
  ret.height*=f;
  return ret;
}

rect r;
//assign fields here
r=r*5;
+2

, ++ ( C), - . , . ? , - ? , , .

, , ?

+2

, . , "" "-".

rect a_rect[100];
int factor;
...
// We need to multiply all members of all elements of `a_rect` array by `factor`

// Prepare index array
int rect::*rect_members[4] = { &rect::x, &rect::y, &rect::width, &rect::height };

// And multiply
for (i = 0; i < 100; ++i)
  for (j = 0; j < 4; ++j)
    a_rect[i].*rect_members[j] *= factor;

, , rect_members, .

, , . "-" , , .

, , a static const

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

  static int rect::* const members[4];
};

int rect::* const rect::members[4] = { &rect::x, &rect::y, &rect::width, &rect::height };

, s.*rect::members[i].

+1

:

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

do_something, int

0

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

:

  • template<class T> class Array (. ),
  • , - .
  • , ( * / )
  • multiply, .
0

, , - , Microsoft DirectX.

union Rect
{
    struct
    {
        int x;
        int y;
        int width;
        int height;
    };

    int members[4];
};

void multiply(Rect& rect, int factor)
{
    for(int i = 0; i < 4; i++)
    {
        rect.members[i] *= factor;
    }
}
0

There are some problems associated with inheriting from standard classes; but if you agree to accept these problems, you can do something similar to what others have suggested, but use it instead std::valarray. It would look like this:

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

In doing so, you inherit the vector operations defined on std::valarray<int>.

I would not recommend this approach. I just suggest that this can be done.

0
source

All Articles