lock3 / meta

123 stars 11 forks source link

new-splice-syntax: data member curiosity #293

Closed rbock closed 3 years ago

rbock commented 3 years ago

Hi,

While playing with the new splice syntax, I noticed that reflecting data members of objects does not seem to work?

struct X
{
  int m;
};

template<typename T>
constexpr auto copy_object_direct(T&& t)
{
  return t;
}

template<typename T>
constexpr auto copy_object_semi_direct(T&& t)
{
  // This succeeds to reflect a expression which is not constexpr.
  return [< reflexpr(t) >];
}

template<typename T>
constexpr auto copy_member_direct(T&& t)
{
  return t.m;
}

template<typename T>
constexpr auto copy_member_semi_direct(T&& t)
{
  return [< reflexpr(t.m) >];
  //                 ^^^
  //error: reflection reflects an expression which is not constexpr
}

int main(int argc, char** argv)
{ 
  auto x = copy_object_direct(X{argc}); // Works
  auto y = copy_object_semi_direct(X{argc}); // Works
  auto b = copy_member_direct(X{argc}); // Works
  auto c = copy_member_semi_direct(X{argc}); // Fails
}
DarkArc commented 3 years ago
template<typename T>
constexpr auto copy_member_semi_direct(T&& t)
{
  return [< reflexpr(t.m) >];
  //                 ^^^
  //error: reflection reflects an expression which is not constexpr
}

Hey, so, this could work in the future, but as it stands we don't really reflect and splice expressions. For the moment things are still focused on entities, so you can successfully rewrite this as:

template<typename T>
constexpr auto copy_member_semi_direct(T&& t)
{
  return [< reflexpr(t) >].m;
  // or
  return [< reflexpr(t) >].[< reflexpr(X::m) >];
}
rbock commented 3 years ago

Thanks! That gives me some food for thought :-)