Is there a way of applying a function to each member of a struct in c++?

后端 未结 13 994
轻奢々
轻奢々 2021-01-13 02:31

You have a simple struct, say:

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

And you want to multiply

相关标签:
13条回答
  • 2021-01-13 03:15

    If all the values fit into a 128-bit vector, then you could use SIMD instructions to multiply them all at once. For example Intel's Integrated Performance Primitives (IPP) has primitives for addition, subtraction, multiplication etc. on vectors.

    It's probably overkill unless you are doing a lot of compute intensive operations.

    0 讨论(0)
  • 2021-01-13 03:15

    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

    0 讨论(0)
  • 2021-01-13 03:15

    A solution via a new class:

    • Create a class with a template<class T> class Array generic array, (see how),
    • Fill the array with your properties, one property as an element of the array.
    • Ensure all types can be multiplied by a numeric value (or overload the * operator for a type if necessary / create a specific method for that object)
    • Create a method multiply that performs a loop on the array and multiplies each element by a given value.
    0 讨论(0)
  • 2021-01-13 03:16

    No; there is no way to iterate over the members of a struct.

    In this particular case, though, you can accomplish your goal by using an array:

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

    (note that this example doesn't make much sense (why would you multiply x, y, height and width by two?) but it demonstrates a different way to solve this sort of problem)

    0 讨论(0)
  • 2021-01-13 03:16

    Well, not directly. But you can achieve that by using an additional temporary "index" array of pointers of pointer-to-member type.

    For example

    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;
    

    Of course, if you need to do it often, you can use a permanent index array rect_members initialized at the program startup.

    Note that this method does not employ any hacks, as some other methods do. Pointers of pointer-to-member type are rarely used, but this is actually one of the things they were introduced for.

    Again, if you need to do it often, the proper thing to do would be to make the pointer array a static const member of the struct

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

    and when you need to iterate over these members, you'd just access struct elements as s.*rect::members[i].

    0 讨论(0)
  • 2021-01-13 03:19

    Like everyone has said, you can't do it directly, but there's nothing stopping you from overloading the * operator:

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

    then you can do this

    rect r;
    //assign fields here
    r=r*5;
    
    0 讨论(0)
提交回复
热议问题