c++reflectionmetaprogrammingc++26

Using C++26 reflection's to inject a struct's name into another struct?


To better understand C++26's reflection, I would like to understand how we can reflect on the name of a struct to inject it in another one (potentially replacing its body, just keeping the name)

For example, given :

struct inner1 {};
struct inner2 {};

template <class T>
struct outer {
    struct /*gets the concrete name of T*/ {
        static constexpr int value = 5;    
    };
};

I would like to replace /*gets the concrete name of T*/ with some C++26's reflection so that the following compiles and displays 5 twice.

std::cout << outer<inner1>::inner1::value << std::endl;
std::cout << outer<inner2>::inner2::value << std::endl;

How to generalize it to a variadic to that :

outer<inner1, inner2>::inner1::value
outer<inner1, inner2>::inner2::value

work?


Solution

  • TL;DR: No.

    The C++26 proposal represents three broad categories of operations: the conversion of an entity into a (constant expression) value which represents that entity (ie: reflection), introspection of the properties and entities of a reflection value, and the "splicing" of a reflection value into the entity it represents (ie: reification).

    What you want is quite different. What you want is to reflect over ::inner1, get its name as a string, then convert that string into a grammatical identifier in the middle of a declaration, such that it declares a new entity (outer<inner1>::inner1) with a name that happens to correspond to the previous one.

    This cannot be done in the C++26 proposal. If r is a reflection of ::inner1, then typename[: r :] would not do what you want. That reification refers to the specific entity ::inner1, and struct ::inner1 {...}; is not valid syntax.

    Nothing about how the proposal is defined prevents something like this from being doable in the future. But at present, converting a constant expression string into an identifier which you can place in a declaration isn't allowed.