TGViewer
C++ - Reddit C++ - Reddit @r_cpp · 230 subscribers
Post #25143 11
C++ reflections: Getting a reflection of a type of a pointer to member, from a reflection of a member is difficult

I am going to argue that we're missing a fairly basic metafunction in C++26. While there are ways around it, none is without downsides. Let's explore!

The title is a mouthful, but I'm talking about this:

struct showcase {
void mem_fun() const {};
};

constexpr std::meta::info mem_fun_refl = ^^showcase::mem_fun;
constexpr std::meta::info mem_fun_ptr_refl = add_pointer(type_of(mem_fun_refl));

Unfortunately, that last line is just nonsense, because the type of `mem_fun` is `void() const`,
which looks similar to a free function type, with the extra cv qualifier.
`add_pointer`, whether the one in `<meta>` or in `<type_traits>` does not work there and
just produces the same type, unchanged.

 

Things get more confusing if `mem_fun()` does not have a cv qualifier. In that case, its type looks
just like a free function type. Now `add_pointer()` compiles and does the wrong thing.

So `add_pointer()` is not useful at all for this purpose.

 

One option that sometimes works is address-splicing:

constexpr std::meta::info mem_fun_refl = ^^showcase::mem_fun;
constexpr std::meta::info mem_fun_ptr_refl = ^^decltype(&[:mem_fun_refl:]);

That comes with a constraint that `mem_fun_refl` is a constant expression *in the current context*.
In other words, this approach fails when `mem_fun_refl` is an argument to a `consteval` function. I.e. the following does not compile:

consteval std::meta::info to_ptr(std::meta::info thing) {
return ^^decltype([:thing:]);
}

Okay, but we can make `std::meta::info thing` a template parameter. This is what I ended up doing in my project.

template<std::meta::info thing>
consteval std::meta::info to_ptr() {
return ^^decltype([:thing:]);
}

That works, but now whoever calls `to_ptr<thing>()` needs to also have `thing` be a constant expression in that scope. In other words, we end up with propagating "this has to be a template" up the call stack.

 

One last attempt: can we manually assemble a pointer to member's type? Something like

[:return_type:] ([:parent_type:]::*)([:parameter_types:]...)
[:return_type:] ([:parent_type:]::*)([:parameter_types:]...) const
[:return_type:] ([:parent_type:]::*)([:parameter_types:]...) const volatile
[:return_type:] ([:parent_type:]::*)([:parameter_types:]...) volatile
[:return_type:] ([:parent_type:]::*)([:parameter_types:]...) noexcept
[:return_type:] ([:parent_type:]::*)([:parameter_types:]...) const noexcept
[:return_type:] ([:parent_type:]::*)([:parameter_types:]...) const volatile noexcept
[:return_type:] ([:parent_type:]::*)([:parameter_types:]...) volatile noexcept

We have all of the needed info:

bool is_noexcept = std::meta::is_noexcept(thing);
bool is_const = std::meta::is_const(thing);
bool is_volatile = std::meta::is_const(thing);
auto return_t = std::meta::return_type_of(thing);
auto parameters = parameters_of(type_of(thing));
auto parent = type_of(parent_of(thing));

The trouble is now doing the manual assembly without actually splicing anything, because `thing` might not be a constant expression.

This is doable, but is quite involved:

template<bool is_const, bool is_volatile, bool is_noexcept, typename R, typename P, typename...Args>
struct assemble_ptr_to_member {
using ptr = std::condtional_t<is_const,
std::conditional_t<is_volatile,
std::conditional_t<is_noexcept, R (P::*)(Args...) const volatile noexcept, R (P::*)(Args...) const volatile>,
std::conditional_t<is_noexcept, R (P::*)(Args...) const noexcept, R (P::*)(Args...) const>,
std::conditional_t<is_volatile,
std::conditional_t<is_noexcept, R (P::*)(Args...) volatile
More from @r_cpp
  1. Oct 3, 2026Upcoming C++ User Group meetings in October https://meetingcpp.com/meetingcpp/news/items/U…
  2. Oct 3, 2026Transcoding UTF-8 to UTF-16 with replacement at gigabytes per second https://lemire.me/blo…
  3. Oct 3, 2026EDG C++ fronted now released as open source https://edgcpp.org/#transition https://redd.it…
  4. Oct 3, 2026Arno Lepisk: Linux shared libraries https://youtu.be/IJASMkkGco8 https://redd.it/1wuvxmh @…
  5. Oct 3, 2026Lets explore the stack https://meetingcpp.com/blog/items/Lets-explore-the-stack.html https…
  6. Oct 3, 2026C++ Show and Tell - October 2026 Use this thread to share anything you've written in C++.…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →