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

后端 未结 13 992
轻奢々
轻奢々 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 02:57

    If you can re-arrange your struct to take be a union instead, you can do something similar to what Microsoft has done with 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 讨论(0)
  • 2021-01-13 02:59

    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

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

    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.

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

    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.

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

    horrific hack

    int *arr = (int*)&my_rect;
    for (int i = 0; i < sizeof(rect)/sizeof(int); i++)
    {
         arr[i] *= factor;
    }
    
    0 讨论(0)
  • 2021-01-13 03:12

    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.

    0 讨论(0)
提交回复
热议问题