Search code examples
c++boostpreprocessor

Boost preprocessor to pass all struct arguments in a function


Is it possible to pass all the members of a struct in a function using boost preprocessor APIs I have something like this but does not compile.

#include <iostream>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/seq/variadic_seq_to_seq.hpp>
#include <boost/preprocessor/seq/elem.hpp>

// Define a macro to generate code for passing a struct member to a function
#define PASS_MEMBER_TO_FUNCTION(r, structName, elem) \
    function(BOOST_PP_SEQ_ELEM(0, elem), structName.BOOST_PP_SEQ_ELEM(1, elem));

// Define a macro to iterate over struct members and pass them to a function
#define PASS_MEMBERS_TO_FUNCTION(structName, members) \
    BOOST_PP_SEQ_FOR_EACH(PASS_MEMBER_TO_FUNCTION, structName, BOOST_PP_VARIADIC_SEQ_TO_SEQ(members))

// Example struct
struct MyStruct {
    int height;
    double width;
    const char* name;
};

// Example function that takes struct members
void function(int value, double width, const char* name) {
    // Your function implementation here
    std::cout << "Value: " << value << ", Width: " << width << ", Name: " << name << std::endl;
}

int main() {
    // Usage example
    MyStruct myStruct{10, 20.5, "example"};
    PASS_MEMBERS_TO_FUNCTION(myStruct, ((int, height))((double, width))((const char*, name)));

    return 0;
}

Solution

  • Using Boost PFR you don't need a preprocessor:

    std::apply(function, boost::pfr::structure_tie(myStruct));
    

    Demo Live On Coliru:

    #include <boost/pfr.hpp>
    #include <iostream>
    
    struct MyStruct {
        int         height;
        double      width;
        char const* name;
    };
    
    // Example function that takes separate parameters
    void function(int value, double width, char const* name) {
        std::cout << "Value: " << value << ", Width: " << width << ", Name: " << name << std::endl;
    }
    
    int main() {
        // Usage example
        MyStruct myStruct{10, 20.5, "example"};
        apply(function, boost::pfr::structure_tie(myStruct));
    }
    

    Printing

    Value: 10, Width: 20.5, Name: example