J'ai implémenté la fonctionnalité de l'espace de noms std :: rel_ops en tant que classe de base de modèle (elle définit tous les opérateurs de comparaison en utilisant uniquement les opérateurs < et ==). Pour moi c'est un peu bizarre que cela fonctionne (jusqu'à présent) correctement, aussi je suis préoccupé par les 'hacks' utilisés. Quelqu'un peut-il évaluer le code suivant et dire si je suis juste chanceux de travailler ou si c'est une pratique courante de faire des choses comme ça.La fonctionnalité std :: rel_ops en tant que classe de base. Est-ce une solution appropriée?
template <typename T>
class RelationalOps {
public:
inline bool operator!=(const T &rhs) const
{
const T& lhs = static_cast<const T&>(*this);
return !(lhs == rhs);
}
inline bool operator<=(const T &rhs) const
{
const T& lhs = static_cast<const T&>(*this);
return ((lhs < rhs) || (lhs == rhs));
}
inline bool operator>(const T &rhs) const
{
const T& lhs = static_cast<const T&>(*this);
return !((lhs < rhs) || (lhs == rhs));
}
inline bool operator>=(const T &rhs) const
{
const T& lhs = static_cast<const T&>(*this);
return !(lhs < rhs);
}
};
Vous utilisez un idiome C++ appelé le modèle de modèle curieusement récurrent (CRTP). C'est une méthode puissante que j'ai utilisée plusieurs fois moi-même. Une référence au T est parfois faite avec une méthode spéciale: 'T & Base() const {return static_cast (* this); } '. Si vous apprenez, vous allez bien. Si vous voulez définir des opérateurs, vous devriez regarder Boost.Operators, tout comme usta recommandé. –
Je devrais probablement aussi suggérer de meilleures façons de définir les opérateurs comme ceci si vous avez besoin de le faire manuellement: définissez 'lhs <= rhs' en termes de'! (Rhs rhs' en termes de 'rhs
usta
La spécification 'inline 'sur toutes ces fonctions est redondante, car les fonctions définies dans un corps de classe sont implicitement en ligne. – Mankarse