Bonjour à tous
Je construis actuellement une bibliothèque pleine de builders.
Comme ils sont extrêmement répétitifs, j'ai opté pour une macro générant un champ privé et un setter
L'idée est de pouvoir chainer les appels, à la façon du "named parameter".
Supposons, la classe suivante:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 #define MACRO_BUILDER_PROPERTY(Self, Type, Name) \ private:\ Type m_##Name;\ public:\ Self& Name(Type const& Name) {m_##Name = Name; return *this;}
Cela génère:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 class BiduleBuilder { MACRO_BUILDER_PROPERTY(BiduleBuilder, int, valeur) MACRO_BUILDER_PROPERTY(BiduleBuilder, optional<std::string>, nom) public: Bidule build(); };
Cela permet alors d'écrire BiduleBuilder().valeur(1).nom(std::string("coin coin")).build();.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 private:class BiduleBuilder { int m_valeur; public: BiduleBuilder& valeur(int const& valeur) {m_valeur = valeur; return *this;} private: optional<std::string> m_nom; public: BiduleBuilder& nom(optional<std::string> const& nom) {m_nom = nom; return *this;} public: Bidule build(); };
Jusque là, tout va bien. Les services rendus sont satisfaisant.
Mais pour des raisons d'ergonomies, on voudrait pouvoir se passer de la construction explicite du std::string dans le cas d'un optional<std::string> (ou en fait de tout optional<...>)
Et c'est là que le bât blesse.
La seule solution que permet optional (de boost ou prochainement de std), c'est de fournir aussi BiduleBuilder& nom(std::string const& nom);.
Donc, il faut que la macro réfléchisse comme une grande pour l'ajouter si besoin est, ou qu'elle ajoute une fonction dont l'appel sera impossible si on n'est pas dans le cas d'une optional.
J'ai bien pensé à enable_if, mais ce n'est possible que sur une template.
Que me conseillez-vous?
Partager