Part of C++26 Series Explore the series

In the previous post I have discussed the basic usage of C++26’s latest (still experimental) feature called reflection. In this post we will look into a more concrete problem which many of us have come across called JSON serialization. We often receive the data in the form of an object of a user defined class. And what we need to do is to format it in JSON format which means to associate the data member names in the class definition with their respective values and put them in a JSON structure. First lets have a look at a hypothetical CanDataSource class as below:

This represents the CAN data that is being received from some source and is subject to further processing into JSON format by the receiver. Along with this we also have another structure representing the retry policies that are applied for transmitting the CAN data packets as the following:

Notice that the RetryPolicy is part of the CanDataSource class hence is formatted into JSON as a part of the CanDataSource object when received at the receiver. Now, to serialize this CanDataSource object into a JSON format we can write a manual serializer implementation like the below:

A very similar implementation for the policy data would be as follows:

These implementations are supported by Poco library which provides in-built functions to handle JSON data. Notice this implementation is hard coding each member of the CanDataSource class into its corresponding string name that needs to be attached to represent it in the JSON format.

The video below provides a quick visual introduction to JSON serialisation:

I have briefly discussed the down side of this kind of manual implementation in my last post. One of the obvious issue is that is any change in the class definition (addition or deletion of any data member) has to be followed by changes in the code. Now with reflection in C++26, the beauty is that you can reflect the non static data members of the class using the std::meta::info extracted by ^^T expression and the std::meta::nonstatic_data_members_of function in the following way:

This will return a std::vector<std::meta::info>. To iterate over it using template for you need to convert it into a range backed by static storage. One way to do that is:

Now the members can be iterated over using template for like the following:

You can read more about template for here. The std::meta::identfier_of function returns a std::string_view and can be printed as follows on the console:

There may be some additional cleaning you may have to do. For example, if you class members are prefixed with m_ then you might like a helper function to remove that somewhat like the following:

And finally, you may like a function template that will take a reference to a JSON object, a key, and its corresponding value and will add it to the JSON object. A possible implementation will look like the following:

Now if your CanDataSource changes, there is no need to modify the code; it will be automatically reflected in the JSON output.

Full Listing

Compile and Run

I have curtailed the output to fit the code window. The full sourc code is available from github link at the bottom of this post. Hope this helps. I will come up with more examples shortly. For details on how to setup the C++26 compilation environment, please refer to this post.

GITHUB REPOSITORY
C++26 Reflection Source Code

The complete source code used in this article is available on GitHub.

View Source Code on GitHub

C++26 Series

Follow my C++26 series as I explore the language’s new features
through practical examples.

  1. 01 Compile Your First C++26 Program with GCC 16.1
  2. 02 C++26: What Is template for?
  3. 03 C++26: What Is Reflection and How Do You Use It?
  4. 04 C++26 Reflection: Simplifying JSON Serialization
  5. 05 C++26 Reflection Annotations: Automated Member Validation
  6. 06 C++26 Contracts: What Do They Add Beyond Manual Checks and Assertions?

Discover more from Tech For Talk

Subscribe to get the latest posts sent to your email.

Leave a Reply