enable_if pour activer une fonction non template
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".
Code:
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;} |
Supposons, la classe suivante:
Code:
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 génère:
Code:
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();
}; |
Cela permet alors d'écrire BiduleBuilder().valeur(1).nom(std::string("coin coin")).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?