Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[struct_pack] how to support derivated struct or derivated class? #346

Closed
manuel76413 opened this issue Jul 2, 2023 · 10 comments
Closed

Comments

@manuel76413
Copy link

namespace yltlib
{
struct myBase
{
int a;
};

struct Derived //: public myBase //use derivated report error while compiling
{
int a;
std::string b;
};

inline
int test_struct_pack()
{
Derived data{.a=42,.b="asdfaf"};
std::ofstream writer("struct_pack_demo.data", std::ofstream::out | std::ofstream::binary);
struct_pack::serialize_to(writer, data);
fmt::print("data = a.{},b.{}\n", data.a,data.b);
writer.close();

std::ifstream ifs("struct_pack_demo.data", std::ofstream::in | std::ofstream::binary);
auto data1 = struct_pack::deserialize<Derived>(ifs).value();
ifs.close();
fmt::print("data1 = {}\n", data1.b);
return 0;

}
}

the problem is cannot support derivated struct and cannot support class objects serialization/deserialization.
do you have any plans to improve these two features?

@poor-circle
Copy link
Collaborator

struct_pack support class now. But all data member should be public.

@poor-circle
Copy link
Collaborator

poor-circle commented Jul 2, 2023

We don't support derivated struct/class, because struct_pack use structured binding to support static reflection, and it's not allowed to structured bind a derivated object. Maybe I will add a macro such as

class myBase
{
int a;
};

class Derived : public myBase
{
std::string b;
REFLECTION(a,b);
};

to support static reflection so we can support derivated object.

@manuel76413
Copy link
Author

yes, this feature is useful.

@manuel76413
Copy link
Author

struct_pack support class now. But all data member should be public.

oh no no no, I have tested, but it didn't support serializing/deserializing class objects even without derived and with public attributes.

@poor-circle
Copy link
Collaborator

struct_pack support class now. But all data member should be public.

oh no no no, I have tested, but it didn't support serializing/deserializing class objects even without derived and with public attributes.

Could you show me your class?

@manuel76413
Copy link
Author

manuel76413 commented Jul 3, 2023

class mybasecls
  {
  public:
    int a;
    int b;
    int c;
    std::string d;
  public:
    mybasecls(int _a, int _b, int _c, std::string _d)
      : a(_a)
      , b(_b)
      , c(_c)
      , d(_d)
    {};
    ~mybasecls() {};
    void fun() {};
  };

    {
      mybasecls a{32,35,235,"dafd"};
      std::ofstream writer("struct_pack_demo1.data",
                           std::ofstream::out | std::ofstream::binary);
      //struct_pack::serialize_to(writer, a);
      fmt::print("mybasecls = a.{},b.{}\n", a.a,a.b);
      writer.close();
    }

yes, when uncomment the serialize_to line, compiling not pass, reporting errors like:

struct_pack_impl.hpp:1460: error: C2338: static_assert failed: 'std::is_aggregate_v<std::remove_cvref_t>'
struct_pack_impl.hpp(1460): error C2338: static_assert failed: 'std::is_aggregate_v<std::remove_cvref_t>'
...

@poor-circle
Copy link
Collaborator

poor-circle commented Jul 3, 2023

OK, let I declare that struct_pack only support user-defined struct/class which are aggregated now.

  1. You can just remove your constructor then the code work. Without user-defined constructor, your class is aggregate.
  2. If you want to keep your constructor. The class is not aggregated. We don't support non-aggregated user-defined struct now. In this case, you can workaround by those step:
    a. keep a default constructor
    b. specialize struct_pack::members_count.
    c. delete all static_assert about aggregate in struct_pack_impl.hpp
class person {
 public:
 int age;
 std::string name;

 person(){};

 person(int age, std::string_view name):age(age),name(name){}

  auto operator==(const person& rhs) const {
    return age == rhs.age && name == rhs.name;
  }
};

template<>
constexpr std::size_t struct_pack::members_count<person> = 2;

The workaround is ugly, and the the best way to support non-aggregated user-defined struct is to use macro like #346 (comment). It's in my todolist.

@manuel76413
Copy link
Author

OK, thanks.
struct_pack is a creative library with many good points,
I wait for your update to support a non-aggregated user-defined struct.
if this lib can support derived struct/class, then it will be caught more attention.

@poor-circle
Copy link
Collaborator

poor-circle commented Jul 24, 2023

See #382, now struct_pack support non-aggregated type by macro. It can also support derivated struct/class.

@poor-circle
Copy link
Collaborator

Fixed by #382.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants