Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apply the same function to each data member - Transform on heterogeneous types sort of thing

Tags:

c++

c++11

Consider the following struct:

struct Test {
   char a;
   short b;
   int c;
   long long d;
   void transformTest() {
      // Pseudo
      foreach datamember (regardless of type) of Test
          call someTransform(datamember)
   }
};

We could also pass a lambda, function pointer, functor, whatever into the transformTest(), that's not my concern as of right now.

What's the best way to do this?

like image 223
ScarletAmaranth Avatar asked Feb 16 '23 01:02

ScarletAmaranth


2 Answers

The best way is to do it explicitly:

someTransform(a);
someTransform(b);
someTransform(c);
someTransform(d);

Of course, you'll need an appropriate number of overloads of someTransform().

If you really, really don't like that, there's always Boost Fusion. With that you can put your values together in a structure which the library understands and then can iterate over. This won't be worth doing for simple use cases.

like image 194
John Zwinck Avatar answered Feb 17 '23 14:02

John Zwinck


Sounds like a case for Boost Fusion and its for_each() function combined with BOOST_FUSION_ADAPT_STRUCT. This stuff can work some miracles! Here's an example on how you can do it:

#include <boost/fusion/include/algorithm.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <iostream>

using namespace boost::fusion;

struct Print
{
    template <typename T>
    void operator()( T && t ) const
    {

        std::cout << t << ' ';
    }
};

struct Test {
    char a;
    short b;
    int c;
    long long d;

    void printTest() const;
};

BOOST_FUSION_ADAPT_STRUCT(
    Test,
    (char, a)
    (short, b)
    (int, c)
    (long long, d)
    )

void Test::printTest() const
{
    for_each ( *this, Print() );
}

int main()
{
    const auto t = Test();
    t.printTest();
}
like image 45
Ralph Tandetzky Avatar answered Feb 17 '23 14:02

Ralph Tandetzky