How to check if class has pointers in C++14

孤人 提交于 2020-01-14 02:00:02

问题


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?


回答1:


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.




回答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.




回答3:


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


来源:https://stackoverflow.com/questions/32880990/how-to-check-if-class-has-pointers-in-c14

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!