PrevUpHomeNext

std::meta::define_aggregate, c++26 reflection example


> Start
> std::meta::define_aggregate
> c++ example
> Back: Home

c++, c++26 reflection:

std::meta::define_aggregate

std::meta::data_member_spec

std::meta::data_member_options

Requires gcc 16.1.

Gcc is ahead of visual c++ and clang to support c++26 reflection.

std::meta::define_aggregate

std::meta::define_aggregate can be used to finish defining an incomplete class type.

The members reflection range must be specified by
a range of std::meta::data_member_spec
by using the first param as member type and
using a member name specified by std::meta::data_member_opitons.

namespace std::meta
{
	template <
		std::meta::reflection_range range_type
			= std::initializer_list<std::meta::info>
	>
	consteval std::meta::info define_aggregate(
		std::meta::info,
		range_type &&
	);
}

For example:

class impl;
consteval
{
	std::meta::define_aggregate(
		^^impl,
		std::vector<std::meta::info>{
			std::meta::data_member_spec(^^int,
				std::meta::data_member_opitons{.name="int_v"}),
			std::meta::data_member_spec(^^float,
				std::meta::data_member_opitons{.name="float_v"}),
			std::meta::data_member_spec(^^char,
				std::meta::data_member_opitons{.name="char_v"})
		}
	);
}

Here it defines incomplete class impl,
and add three data members to the class impl :

int int_v;
float float_v;
char char_v;

To avoid error code :

c++ example

Tested on gcc 16.1.

Some code idea from open-std and cppreference can not be compiled on current c++ compiler. This code fix it to let it compile.

Gcc is the best to compile c++ reflection code.

#include <meta>
#include <iostream>
#include <vector>
#include <array>

namespace nss
{
	template <typename point_type, std::size_t N>
	class hide
	{
	public:
		class trans;
	public:
		consteval
		{
			// Stage-1: store old members of input
			auto old_members = std::meta::nonstatic_data_members_of(
				^^point_type,
				std::meta::access_context::current()
			);

			// Stage-2: make new members
			std::vector<std::meta::info> members{};
			for (auto mem: old_members)
			{
				members.push_back(
					std::meta::data_member_spec(
						std::meta::substitute(
							^^std::array,
							std::vector<std::meta::info>{
								std::meta::type_of(mem),
								std::meta::reflect_constant(N)
							}
						),
						std::meta::data_member_options{
							.name = std::meta::identifier_of(mem)
						}
					)
				);
			}

			// Stage-3: define it
			std::meta::define_aggregate(^^trans, members);
		}
	};	// class hide
}	// namespace nss


namespace src
{
	class point
	{
	public:
		double x{};
		double y{};
		double z{};
	};
}

int main()
{
	nss::hide<src::point, 10>::trans points{
		{1,2,3,4,5,6,7,8,9,0},
		{0,1,2,3,4,5,6,7,8,9},
		{9,0,1,2,3,4,5,6,7,8}
	};

	for (unsigned int i=0; i<points.x.size(); ++i)
	{
		std::cout << points.x[i] << " " << points.y[i] << " " << points.z[i] << std::endl;
	}
}

The example transforms the class structure from src::point to the following code:

class trans
{
public:
	std::array<double, 10> x;
	std::array<double, 10> y;
	std::array<double, 10> z;
};

//////////////////////////////////////////////////////////////////////

Home

//////////////////////////////////////////////////////////////////////

Sat Jul 4 09:53:32 AM UTC 2026

//////////////////////////////////////////////////////////////////////

Helpful

Spaceship 50 Years Alienated

Role

+

Github:
https://github.com/cppfx/cpphtgt

+

Powered by:
B2 Build | boost quickbook

+

Donate

+

@cppfx.xyz


















PrevUpHomeNext