Member list empty when using reflect<T>(), but works fine with reflect(const T&)
Closed this issue · 1 comments
Hi @veselink1
First of all, I would like to thank you for developing such an amazing library for C++. It has helped us a lot.
While I was developing functionalities based on refl-cpp, I noticed some very strange behavior and I can't figure out where it comes from.
Below are some code to reproduce the bheavior. I was trying to write an "recursiveForEach" function for nested reflected types. The code below has nothing to do with recursion as I have tried to minimize the code.
Link to goldbolt
Here's the code itself.
#include <iostream>
#include <https://raw.githubusercontent.com/veselink1/refl-cpp/master/include/refl.hpp>
template<typename T, typename Func>
constexpr void forEach(T&& obj, Func&& func)
{
refl::util::for_each(refl::reflect<T>().members, [&](auto member)
{
func(member(obj));
});
}
template<typename T, typename Func>
constexpr void forEach2(T&& obj, Func&& func)
{
refl::util::for_each(refl::reflect(obj).members, [&](auto member)
{
func(member(obj));
});
}
template<typename T, typename Func>
constexpr void forEachDescriptor(Func&& func)
{
refl::util::for_each(refl::reflect<T>().members, [&](auto member)
{
func(member);
});
}
struct AAA
{
int a, b;
};
REFL_AUTO(
type(AAA),
field(a),
field(b)
)
int main()
{
AAA a{1, 2};
std::cout << "for each with reflct<T>()" << std::endl;
forEach( a, [](auto && member)
{
std::cout << member << ',';
});
std::cout << std::endl;
std::cout << "for each with reflct(const &T)" << std::endl;
forEach2( a, [](auto && member)
{
std::cout << member << ',';
});
std::cout << std::endl;
std::cout << "for each discriptor without passing an instance" << std::endl;
forEachDescriptor<AAA>([](auto member)
{
std::cout << get_display_name(member) << ',';
});
std::cout << std::endl;
std::cout << "end of program" << std::endl;
return 0;
}
I have wrriten 3 wrappers around the for each utility from refl.
The first one takes an instance of the object but uses refl::reflect<T>()
to get the descriptor.
The second one takes an instance of the object but uses refl::reflect(const T&)
to get the descriptor.
The third one does not take an instance of the object but instead, it iterate through the members using refl::reflect<T>()
to get the descriptor.
In theory, the three usage of reflect should hehave exactly the same but the first one will result in empty members. The third one also uses refl::reflect<T>()
but different from the first funtion, it works.
When you run this code, you should see the following output
for each with reflct<T>()
for each with reflct(const &T)
1,2,
for each discriptor without passing an instance
a,b,
end of program
I have tried this on gcc 9.4, 10.2, 10.3, all resulted in the same behavior.
I have found the solution.
reference needs to be removed before passing into reflect
std::remove_reference_t solved it.