veselink1 / refl-cpp

Static reflection for C++17 (compile-time enumeration, attributes, proxies, overloads, template functions, metaprogramming).
https://veselink1.github.io/refl-cpp/md__introduction.html
MIT License
1.05k stars 76 forks source link

GetDateFormat getter vs. the Win32 API #57

Closed rpatters1 closed 2 years ago

rpatters1 commented 2 years ago

I've got a class with the following:

class MyClass
{
public:
   void SetDateFormat(int x);
   int GetDateFormat() const;
...
  // many dozens more getters and setters so that REFL_AUTO is not an option, if it matters.
};

REFL_TYPE(MyClass)
   REFL_FUNC(SetDateFormat, property())
   REFL_FUNC(GetDateFormat, property())
... // a lot more
REFL_END

constexpr auto type = refl::reflect<MyClass>();
constexpr auto members = get_members(type);

for_each(members, [&](auto member)
{
   if constexpr (refl::descriptor::is_property(member)
      if constexpr (refl::descriptor::is_writable(member))
      {
         auto reader = refl::descriptor::get_reader(member); // fails in Windows VS 2022
      }
      else
         ...
});

The issue is that GetDateFormat is a macro defined by the Window API. It messes up get_reader. Oddly, it doesn't mess up the for_each loop. If I change the code so that it doesn't call get_reader it compiles, and I can successfully process the getter (though not correctly for my requirements).

I have tried #undef GetDateFormat, but that makes no difference. I tried (GetDateFormat), which normally is how you prevent macro expansion, but that doesn't work inside a macro. I would try to make a change to get_reader but I don't understand the code well enough. I could brute force my way out of this by changing the name, but that has downline consequences beyond my control.

If you have any suggestions, I would appreciate them.

veselink1 commented 2 years ago

for_each iterates all reflected members, is_property selectes functions with property() specified, is_writable selects those properties which have an overload that looks like a setter (non-const function with 1 parameter; see def).

GetDateFormat expands to either GetDateFormatA or GetDateFormatW, depending on the UNICODE macro. I believe what you've effectively declared in your code is a member int GetDateFormatW() const, which you have then reflected with REFL_FIELD. get_reader attempts to find a matching getter for SetDateFormat called GetDateFormat, but there is only GetDateFormatW, so it fails.

You say you have tried #undef GetDateFormat and it makes no difference? Can you post the error messages for both of these, or even better, a Compiler Explorer link?

rpatters1 commented 2 years ago

I must have been too sleep-deprived last night. #undef is actually working this morning.