Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8316329
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 8, 20262026-06-08T21:20:18+00:00 2026-06-08T21:20:18+00:00

I have a multiple classes each with different member variables that are initialized trivially

  • 0

I have a multiple classes each with different member variables that are initialized trivially in a constructor. Here is an example:

struct Person
{
    Person(const char *name, int age)
        :
        name(name),
        age(age)
    {
    }
private:
    const char *name;
    int age;
};

Each has an associated print<>() function.

template <>
void print<Person>(const Person &person)
{
    std::cout << "name=" << name << "\n";
    std::cout << "age=" << age << "\n";
}

This code is error prone since the parameter list is replicated in four places. How can I rewrite the code to avoid this duplication? I’d like to use the preprocessor and/or templates.

For example, could I use the X-args preprocessor technique — something like this?

#define ARGUMENTS \
    ARG(const char *, name) \
    ARG(int, age)

struct Person
{
    Person(LIST_TYPE_NAME_COMMA(ARGUMENTS))
       :
       LIST_NAME_INIT(ARGUMENTS)
    {
    }
private:
    LIST_TYPE_NAME_SEMICOLON(ARGUMENTS)
};

template <>
void print<Person>(const Person &person)
{
   LIST_COUT_LINE(ARGUMENTS)
}

#undef ARGUMENTS

Or better, a template-based approach?

Please don’t question why I want to do this, there are reasoned design decisions that have resulted in multiple similar objects with named parameters. The parameters need to be named member variables for performance reasons. I’m just exploring whether it’s possible to list the parameters and their types only once.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-08T21:20:19+00:00Added an answer on June 8, 2026 at 9:20 pm

    What you need to do is have the preprocessor generate reflection data about the fields. This data can be stored as nested classes.

    First, to make it easier and cleaner to write it in the preprocessor we will use typed expression. A typed expression is just an expression that puts the type in parenthesis. So instead of writing int x you will write (int) x. Here are some handy macros to help with typed expressions:

    #define REM(...) __VA_ARGS__
    #define EAT(...)
    
    // Retrieve the type
    #define TYPEOF(x) DETAIL_TYPEOF(DETAIL_TYPEOF_PROBE x,)
    #define DETAIL_TYPEOF(...) DETAIL_TYPEOF_HEAD(__VA_ARGS__)
    #define DETAIL_TYPEOF_HEAD(x, ...) REM x
    #define DETAIL_TYPEOF_PROBE(...) (__VA_ARGS__),
    // Strip off the type
    #define STRIP(x) EAT x
    // Show the type without parenthesis
    #define PAIR(x) REM x
    

    Next, we define a REFLECTABLE macro to generate the data about each field(plus the field itself). This macro will be called like this:

    REFLECTABLE
    (
        (const char *) name,
        (int) age
    )
    

    So using Boost.PP we iterate over each argument and generate the data like this:

    // A helper metafunction for adding const to a type
    template<class M, class T>
    struct make_const
    {
        typedef T type;
    };
    
    template<class M, class T>
    struct make_const<const M, T>
    {
        typedef typename boost::add_const<T>::type type;
    };
    
    
    #define REFLECTABLE(...) \
    static const int fields_n = BOOST_PP_VARIADIC_SIZE(__VA_ARGS__); \
    friend struct reflector; \
    template<int N, class Self> \
    struct field_data {}; \
    BOOST_PP_SEQ_FOR_EACH_I(REFLECT_EACH, data, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))
    
    #define REFLECT_EACH(r, data, i, x) \
    PAIR(x); \
    template<class Self> \
    struct field_data<i, Self> \
    { \
        Self & self; \
        field_data(Self & self) : self(self) {} \
        \
        typename make_const<Self, TYPEOF(x)>::type & get() \
        { \
            return self.STRIP(x); \
        }\
        typename boost::add_const<TYPEOF(x)>::type & get() const \
        { \
            return self.STRIP(x); \
        }\
        const char * name() const \
        {\
            return BOOST_PP_STRINGIZE(STRIP(x)); \
        } \
    }; \
    

    What this does is generate a constant fields_n that is number of reflectable fields in the class. Then it specializes the field_data for each field. It also friends the reflector class, this is so it can access the fields even when they are private:

    struct reflector
    {
        //Get field_data at index N
        template<int N, class T>
        static typename T::template field_data<N, T> get_field_data(T& x)
        {
            return typename T::template field_data<N, T>(x);
        }
    
        // Get the number of fields
        template<class T>
        struct fields
        {
            static const int n = T::fields_n;
        };
    };
    

    Now to iterate over the fields we use the visitor pattern. We create an MPL range from 0 to the number of fields, and access the field data at that index. Then it passes the field data on to the user-provided visitor:

    struct field_visitor
    {
        template<class C, class Visitor, class T>
        void operator()(C& c, Visitor v, T)
        {
            v(reflector::get_field_data<T::value>(c));
        }
    };
    
    
    template<class C, class Visitor>
    void visit_each(C & c, Visitor v)
    {
        typedef boost::mpl::range_c<int,0,reflector::fields<C>::n> range;
        boost::mpl::for_each<range>(boost::bind<void>(field_visitor(), boost::ref(c), v, _1));
    }
    

    Now for the moment of truth we put it all together. Here is how we can define the Person class:

    struct Person
    {
        Person(const char *name, int age)
            :
            name(name),
            age(age)
        {
        }
    private:
        REFLECTABLE
        (
            (const char *) name,
            (int) age
        )
    };
    

    Here is the generalized print_fields function:

    struct print_visitor
    {
        template<class FieldData>
        void operator()(FieldData f)
        {
            std::cout << f.name() << "=" << f.get() << std::endl;
        }
    };
    
    template<class T>
    void print_fields(T & x)
    {
        visit_each(x, print_visitor());
    }
    

    An example:

    int main()
    {
        Person p("Tom", 82);
        print_fields(p);
        return 0;
    }
    

    Which outputs:

    name=Tom
    age=82
    

    And voila, we have just implemented reflection in C++, in under 100 lines of code.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a multiple ModelForm classes that each represent a different Model. I would
The situation: I have multiple classes that should each hold a variable with a
I have multiple classes that will store similar data for different uses and I
I have multiple classes (controllers) that share a huge chunk of code with each
I have multiple classes that inherit from one base class, and each class is
I have multiple classes in multiple dll's and each dll's may include other. I
Is it a good practice to have multiple XXX : DbContext classes for each
Is it possible to have multiple classes that inherit/extends same class in Google AppEngine
Is it possible to extend multiple classes in Scala. For example if I have
In Django, when you have a parent class and multiple child classes that inherit

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.