Best way to split structure into function argument list

I have a function like:

void funcName(arg1, arg2, arg3[ = someDefault], ... , argN)

      

And I have a structure like

struct Args
{
    arg1;
    ...
    argN;
}

      

Is there any DRY and nice solution to initialize a struct from args functions and send the struct to a function if I can't change the function signature?

+3


source to share


2 answers


Sure, but this is C ++ 11.

struct xy {
    int x, y;
};

template <class... T>
xy f(T... args) {
    return xy{args...};
}

int main() {
    xy a = f(1, 2);
    cout << a.y << endl;
}

      

Real-time example.



By sending structure to function, it looks like you wanted you to want to get each field from the structure in the order they were declared and call the function with them as arguments. Sorry, but there is no pretty way to do this, because it requires compile-time reflection , which can be added to other versions of C ++, but the syntax is not clear yet.

If you can use tuple

structs instead, it's easy.

There's not a pretty way to do this if you absolutely must. There is a Boost Fusion library in there. This allows the reflection of the structure to be added via macros so that they can be converted to tuples.

+3


source


You can do this with macros. This is definitely not pretty, but very compatible (works in C, C ++ 03, etc.):

In the header file args.h

:

#define ARGS_STRUCT ARG(int, arg1) SEP ARG(char *, arg2) SEP ARG(void *, arg3)
#undef ARG
#undef SEP

      

You can declare the structure as

struct Args {
    #define ARG(type, name) type name
    #define SEP ;
    #include "args.h"
};

      

and a function like



int func(
    #define ARG(type, name) type name
    #define SEP ,
    #include "args.h"
);

      

initialize the structure with

struct Args args = {
    #define ARG(type, name) name
    #define SEP ,
    #include "args.h"
};

      

pass to args with

struct Args args;
func(
    #define ARG(type, name) args.name
    #define SEP ,
    #include "args.h"
);

      

Tested, no problem with Clang and Clang ++ (both 6.1).

+1


source







All Articles