bloomberg / clang-p2996

Experimental clang support for WG21 P2996 (Reflection).
https://github.com/bloomberg/clang-p2996/tree/p2996/P2996.md
51 stars 8 forks source link

display_string_of and identifier_of not available #77

Closed Yaraslaut closed 1 month ago

Yaraslaut commented 1 month ago

In some cases display_string_of or identifier_of can not be evaluated, for example: https://godbolt.org/z/KWff1ezx3

template<typename T,typename Tag = decltype([] {})>
struct CreateUniqueT{};

template<typename T>
constexpr auto CreateClass()
{
    return define_class(^T, {
        data_member_spec(^int, {.name="i"}),
        data_member_spec(^int, {.name="j"})
    });
}
int main() {
    constexpr auto created_type = CreateClass<CreateUniqueT<int>>();
    std::println("{}",identifier_of(created_type));
    std::println("{}",display_string_of(created_type));
}

It would be great to have it available for weird entities like one present above

katzdm commented 1 month ago

Hey, @Yaraslaut !

This will be more clear once we've updated the P2996 draft, but the behavior of identifier_of is correct: The function only succeeds when the reflected construct has a name that is an identifier. Since an identifier is a sequence of once or more characters, identifier_of(^decltype([] {})) will fail to be a constant expression since the closure type has no name.

display_string_of, however, should definitely render a string; I've fixed this in 616aa8e. When the change hits godbolt tomorrow, the line

std::println("{}", display_string_of(created_type));

will print:

CreateUniqueT<int, (anonymous type)>

Thanks a lot for the bug report, and thanks for trying out the bleeding edge changes!

Yaraslaut commented 1 month ago

thanks for the fast fix @katzdm I checked, everything is working