6

I've got the classes:

struct A { // has no pointer members, POD - it's fine
  int a, b;
  char c;
};

struct B { // has no pointer members, but not POD - it's still fine
  int a, b;
  std::string s;
};

struct C { // has pointer members, it's not fine
  int a,b;
  char* cs;
};

I need to detect in compile time if any class has the properties of struct C, i.e. has pointers as members.

Short reasoning: I need to assure a user-defined type can be safely serialized and deserialized to some buffer by copying or assignment (e.g. struct A) or by providing user-defined serialize() and deserialize() methods in the class (e.g. struct B and struct c).

If B or C do not have these methods implemented, then compilation should fail, but if A does not have the methods, then the compilation should succeed.

Update:

The solution from Check if a class has a pointer data member works only for:

struct D {
  int* p; // the pointer must be named 'p'
};

This issue is a different case. Can we reopen, please?

Community
  • 1
  • 1
Robert Mutke
  • 2,757
  • 1
  • 16
  • 14
  • Require things people want to serialize to inherit from a serializable interface class? The interface doesn't have to do anything, just a sigil to mark it as such. Also, serializing C++ structs can be a bad idea, even if they are POD. – zstewart Oct 01 '15 at 06:46
  • See http://stackoverflow.com/a/21502331/2508150 – Paolo M Oct 01 '15 at 06:47
  • 7
    There no generic (and standard) way to iterate over the members of any structure, at compile- or run-time. This of course means that there is no way to implement a generic serializer, and just copying a structure to a byte buffer is not a good way to handle serialization. Think about endinaess issues, floating point implementation details, virtual tables, and embedded classes containing pointers will lead to the same problems you have with pointers directly in the structure. – Some programmer dude Oct 01 '15 at 06:52
  • You have to transform your class in something like `std::tuple` to be able to iterate on its member and know if its (direct) members are POD and non pointer. – Jarod42 Oct 01 '15 at 07:42
  • 2
    Guys, this issue is not a duplicate. The other one deals with a single pointer named 'p'. I need a generic solution. – Robert Mutke Oct 01 '15 at 08:01
  • `std::string` contains a pointer inside of it. Is that OK? Also, what about references, nested types? – rustyx Jan 24 '18 at 18:56
  • You can probably do this better with a clang-based parser (e.g. in python). https://clang.llvm.org/docs/IntroductionToTheClangAST.html : Parse the AST tree and verify that your classes have non-pointer attributes. – lwinkler May 31 '22 at 13:39

3 Answers3

2

As of C++17, this is simply not possible.

You can test for a number of traits, but there is no trait that checks data members the way you need. std::is_pod<> (which will be deprecated in C++20) is the best you can get.

alecov
  • 4,882
  • 2
  • 29
  • 55
1

You can try magic_get.

It's a C++14 TMP solution for POD refrection, and it surely has its limitations (e.g. doesn't properly support references, bit fields, etc.), but you can enumerate PODs just the way you want (statically or dynamically), and then apply the std::is_pointer trait to check each field.

Example:

#include <iostream>
#include "boost/pfr/precise.hpp"

struct C {
  int a, b;
  char* cs;
};

int main() {
    C var;
    boost::pfr::for_each_field(var, [](const auto& field, std::size_t idx) {
      std::cout << "field " << idx << ": is_pointer=" << std::is_pointer<std::remove_reference_t<decltype(field)>>() << '\n';
    });
}

Output:

field 0: is_pointer=0
field 1: is_pointer=0
field 2: is_pointer=1
rustyx
  • 80,671
  • 25
  • 200
  • 267
-2

This is an XY problem.

The user that created the class needs to provide the serialize / deserialize functions according to the interface you provide. He knows if the class should be serializabile and if so how it should be done. It's the user responsibility, not yours. All you can do on your part is to provide an easy to use interface and tools to make it easier for the user to make a class serializabile.

Checking if a type has a pointer data member doesn't solve any issue and doesn't help in the slightest. You don't know if the pointer points to something the object owns exclusively, to something shared across objects, or points to a resource not-owned.

bolov
  • 72,283
  • 15
  • 145
  • 224