Dites que vous avez le code suivant:
class A { bool _attribute1; }; // Arbitrarily using std::string, not the point of this question std::string serialize(const A&);
3 Réponses :
Si vous utilisez C ++ 1Z, vous pouvez utiliser une liaison structurée: [Démo en direct] P> P>
Agréable. Recherchez-vous que la fonction de sérialisation utilise ensuite x code>?
@Muscampter tant que vous envisagez de sérialiser uniquement les champs publics de la classe, il est relativement facile à effectuer
Je vois que cela fonctionnerait également avec auto & code>. Que pourrait-on faire sur les députés privés?
@Muscampier Malheureusement, je ne pense pas que cela puisse être étendu aux membres privés / protégés
Je vais essayer de me rappeler que lorsque la plupart des projets industriels sont migrés vers C ++ 17 cinquante ans à partir de maintenant :).
Cet exemple pourrait-il être réécrit dans C ++ 11 à l'aide d'un std :: Cravate Code>
?
@Muscampter non peut faire. std :: cravate code> permet uniquement d'attribuer à son instance de résultat de
std :: tuple code>
Le suivant devrait fonctionner avec C ++ 11. L'idée de base est de répertorier tous les types des membres de données et de définir un nouveau type d'entre eux avec un mixin. Ensuite, il s'agit de mettre un Il existe des cas d'angle qui pourraient le casser, mais peut-être que cela peut fonctionner pour votre code réel. P> Note latérale, il peut être encore simplifié si C ++ 14 est une option: p>
Un peu délicat en effet, il est basé sur un commentaire de @ Samvarshavchik : static_assert code> au bon endroit.
Notez que les membres de données privés sont également pris en compte. P>
Si vous êtes condamné à utiliser C ++ 11 et vous êtes toujours intéressé par Serializing uniquement les champs publics que vous pouvez créer des tests de trait si le type peut être construit à l'aide d'une initialisation de la liste avec des types de paramètres donnés mais même une autre (de TOUT TYPE):
#include <type_traits> struct default_param { template <class T> operator T(); }; template <class T, class...> using typer = T; template <class, class, class... Args> struct cannot_one_more: std::true_type {}; template <class Tested, class... Args> struct cannot_one_more<typer<void, decltype(Tested{std::declval<Args>()..., default_param{}})>, Tested, Args...>: std::false_type { }; template <class...> struct is_list_constructable: std::false_type {}; template <class Tested, class... Args> struct is_list_constructable<Tested(Args...)>: is_list_constructable<void, Tested, Args...> { }; template <class Tested, class... Args> struct is_list_constructable<typer<void, decltype(Tested{std::declval<Args>()...}), typename std::enable_if<cannot_one_more<void, Tested, Args...>::value>::type>, Tested, Args...>: std::true_type { }; struct S { bool b; //bool c; // causes error }; int main() { static_assert(is_list_constructable<S(bool)>::value, "!"); }
Je ne pense pas que ce soit possible.
La seule chose à laquelle je pouvais penser serait une affirmation statique quelque part sur la taille de (a). Par conséquent, si quelque chose est ajouté, quelque chose échouera de compiler jusqu'à ce que le nouveau membre de la classe soit sérialisé et que l'affirmation statique ajustée en conséquence.
Vous pouvez ajouter un script ou un programme personnalisé à vos étapes de Makefile ou IDE Pré-Build pour vérifier que tous les membres de la classe sont inclus dans la fonction.