2009-01-05 6 views
2

J'ai le cas d'utilisation suivant, un struct avec une valeur booléenne et les variables intStruct avec initialisation par défaut du champ booléen?

struct a { 

    int field1; 
    bool field2; 
    bool field3; 

}; 

Je refactoring ce code et l'écriture d'un constructeur pour la struct, le problème est l'initialisation par défaut des champs.

Je ne critique pas une construction linguistique, mais idéalement je voudrais nulle pour faire partie de la langue elle-même

je veux dire que je devrais être en mesure de définir une struct comme

a : field1(null.int), field2(null.bool), field3(null.bool) {} 

C++ ne le permet pas car null.int ou null.bool ne sont pas définis. La seule façon de faire en C++ est

a: field1(-1), field2(false), field3(false) {} 

Répondre

9

Vous pouvez faire

struct a { 
    a():field1(), field2(), field3() { } 
    int field1; 
    bool field2; 
    bool field3; 
}; 

Et tous les champs seront zéro et faux respectivement. Si vous voulez dire que les champs ont une valeur indéterminée, je crains que vous deviez utiliser d'autres techniques. La première consiste à utiliser boost::optional:

struct a { 
    a():field1(int()), field2(bool()) { } 
    optional<int> field1; 
    optional<bool> field2; 
    optional<bool> field3; 
}; 

Feuilles Field3 indéterminée. Accédez aux valeurs avec *field_name. Testez pour une valeur nulle avec field == boost::none ou if(field) { ... }.

3

Un booléen a deux états. C'est ce qui en fait un booléen. Ainsi, dans tout langage fortement typé, un booléen est soit vrai soit faux.

Un entier dans c/C++ (et java) est la représentation binaire directe d'un nombre. Vous pouvez assigner une valeur de ce nombre pour signifier "ce nombre n'a aucune valeur", mais cela n'a pas de sens dans toutes les situations - et si le langage devait en tenir compte, chaque opération mathématique devrait être précédée d'un contrôle - Ça ralentirait vraiment les choses.

Ligne inférieure: Si vous voulez un système de type faible, utilisez une autre langue.

2

Vous semblez vouloir pouvoir dire que les champs sont dans un état indéfini. Cela va à l'encontre des principes d'un langage fortement typé (tel que C++), donc vous n'avez pas de chance.
Si vous voulez vérifier si quelque chose a été défini, vous devez le faire vous-même. Vous pourriez potentiellement utiliser des pointeurs pour résoudre votre problème, mais je ne pense personnellement pas que ce serait une bonne idée. Peut-être que si vous essayiez d'expliquer le vrai problème que vous essayez de résoudre, nous pourrions vous donner de meilleurs conseils.

4

Si vous recherchez un type avec des valeurs {true, false, null}, ce type n'est pas booléen. Cependant, boost::optional<bool> est un tel type. De la même manière, boost::optional<int> peut contenir n'importe quel int, ou aucun int du tout.

1

C'est le moyen de ne pas payer pour tout ce que vous n'utilisez pas et l'initialisation par défaut, et la possibilité d'avoir bool non initialisé est quelque chose dont beaucoup de gens n'auront pas besoin.

Si vous voulez vraiment ce genre de comportement, vous pouvez créer une version nullable du type avec lequel vous travaillez. Quelque chose le long des lignes:

class NullBool { 
    bool m_null; 
    bool m_value; 
    public: 
    NullBool() : m_null(true) {} 
    NullBool(bool value) : m_null(false), m_value(value) {} 
    void isNull() const { 
    return m_null; 
    } 
    void value() const { 
    return m_value; 
    } 
    ... 
    // lots of operations 
    ... 
}; 

Cela devrait probablement être construit comme un modèle de sorte qu'il fonctionne pour plusieurs types de la boîte. Et puisque c'est votre propre type, vous pouvez facilement rendre le constructeur par défaut pour le rendre nul par défaut.

+0

ce modèle serait ... boost :: facultatif ? – xtofl

+0

Il semble que oui, je ne savais pas à ce sujet jusqu'à ce que litb édité son poste pour le mentionner :) – Laserallan

Questions connexes