41 votes

C ++ safe bool wrapper

Je suis en train de concevoir un bool wrapper struct l'application de la sécurité bool idiome.
Le classique de la mise en œuvre de résoudre ce problème est assez trivial: le squelette pourrait être quelque chose comme ceci:

struct Bool final
{
  Bool() = default;

  Bool(bool value)
    : _value{value}
  {}

  explicit operator bool() const {
    return _value;
  }

private:
  bool _value{false};
};

La partie que je suis en train d'essayer d'améliorer la façon dont Bool est construit.
Par exemple je veux éviter implicite rétrécissement de design:

Bool b1(45); // yields warnings, but it compiles
Bool b2{3};  // not ok by standard

J'ai essayé de me blesser à l'aide de modèles, mais sans succès.

Comment pourrais-je le faire fonctionner?

58voto

François Andrieux Points 16034

Vous pouvez y parvenir en supprimant explicitement tous les autres constructeurs.

 struct Bool final
{
    template<class T>
    Bool(T) = delete;

    Bool(bool value);
};
 

24voto

yuri kilochek Points 3643

Ajouter et explicitement supprimer un modèle du constructeur:

template <typename T>
Bool(T) = delete;

Elle correspond à rien d'autre que le réel bool mieux que d'autres constructeurs, et donc d'empêcher la conversion implicite.

18voto

pilkch Points 95

Si vous avez besoin de:
Une variable qui n'est "vrai" ou "faux" et ne peut pas être implicitement converti en int/char/pointeur puis je regarde à l'aide d'un enum class:

enum class Bool {
    False,
    True,
};

14voto

Barry Points 45207

Je suis en train de concevoir un bool wrapper struct l'application de la sécurité bool idiome.

Ne le faites pas.

Le coffre-fort bool idiome n'est pertinente en C++03 et plus tôt - où, si vous exprimez votre type est "truthy" en faisant quelque chose comme:

struct A {
    operator bool() const;
};

vous feriez courir dans toutes sortes de problèmes comme:

A{} + 4;    // ok?!
A{} < 0;    // ok?!
A{} == B{}; // ok if B also has operator bool??!

Ainsi, le coffre-fort bool idiome a été une solution à ce accidentelle de la conversion implicite problème, en utilisant des pointeurs de fonction (bien sûr, des pointeurs de fonction!).

En C++11, nous avons une meilleure solution:

struct A {
    explicit operator bool() const;
};

qui fait exactement ce que nous voulons. En fait, il a été littéralement conçu pour résoudre ce problème. Et tandis que le coffre-fort bool idiome est assez compliqué d'échafaudage, explicit operator bool est super simple à utiliser et juste fait la bonne Chose. Vous n'avez pas besoin d'un wrapper pour elle - c'est plus difficile à utiliser votre enveloppe que d'écrire de la explicit operator bool directement.

En outre, votre enveloppe impose à l'utilisateur (a) non-derivability parce que vous avez fait Bool final et (b) un supplément de bool membre, que vous devez garder en synchronisation, de sorte qu'il présente plutôt que de résoudre des problèmes. Considérez combien de travail il serait pour vous de mettre en place:

template <class T>
struct my_unique_ptr : Bool { ... };

vs

template <class T>
struct my_unique_ptr {
    T* ptr;

    explicit operator bool() const { return ptr; }
};

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X