Comment stocker une sorte de “null” en C++ double ou variable int?
J'ai une classe qui ressemble à ce
struct A {
double a1;
int b1;
double a2;
int b2;
};
J'ai de la lecture d'un fichier de valeurs pour a1
, b1
, a2
, et b2
. La plupart du temps tous les quatre nombres sont sur le fichier, mais parfois il y a seulement deux numéros.
Lorsqu'il y a deux numéros, je veux stocker les valeurs dans a1
, et b1
et je veux stocker "rien" dans a2
et b2
. Si a2
et b2
ont été les pointeurs, j'ai juste pu les affecter à la nullptr
, mais ils ne sont pas des pointeurs.
Il y a une chose que je peux stocker dans double
et int
variables pour indiquer que "rien" est-il stocké?
Je sais Boost.Optional
est disponible, mais j'essaie d'éviter que de la bibliothèque.
Choisissez une valeur que vous connaissez vos variables ne seront jamais prendre et nom il
C'est le problème, je ne sais pas les valeurs de mes variables ne les auront jamais.
Non, ne pas les nommer, il
Si vous ne voulez vraiment pas à utiliser la bibliothèque boost pour une raison quelconque, il est assez simple de rédiger votre propre
Pour en virgule flottante, vous pourriez être en mesure d'utiliser
NULL
. Puis de comparer les variables à NULL
. Les premiers choix sont souvent 0 ou -1C'est le problème, je ne sais pas les valeurs de mes variables ne les auront jamais.
Non, ne pas les nommer, il
NULL
. Donnez-lui un nom unique qui n'entre pas en conflit avec la bibliothèque standard.Si vous ne voulez vraiment pas à utiliser la bibliothèque boost pour une raison quelconque, il est assez simple de rédiger votre propre
optional
pour les types simples - il suffit de placer la valeur et un bool
dans un peu de classe avec une interface adaptée. Si vous souhaitez un soutien non négligeable types (en particulier, les types qui ne peut pas être par défaut construit), puis à l'aide d'une bibliothèque, vous fera économiser un monde de douleur.Pour en virgule flottante, vous pourriez être en mesure d'utiliser
NaN
, mais pour autant que je sais soutien à virgule flottante NaN
n'est pas universelle. Pour le type int
, INT_MIN
être raisonnable, mais vous avez dit que vous ne savez pas de toutes les valeurs de vos variables ne les auront jamais. À la différence pour les pointeurs, il n'y a pas de distinction de valeur "nulL pour les entiers. Étant donné que, votre seul choix est de stocker des informations indiquant si une véritable valeur est stockée ou pas. Si vous le faites avec Boost.Optional
, avec votre propre classe similaire à Boost.Optional
, ou tout simplement par l'ajout de bool
membres est à vous.
OriginalL'auteur jlconlin | 2014-08-28
Vous devez vous connecter pour publier un commentaire.
Vous pouvez assigner NAN pour le double a2, qui indique également que l'int b2 n'est pas valide.
Cette page pour NAN utilisation.
std::numeric_limits<double>::quiet_NaN()
etstd::nan("1")
?Je pense que quiet_NaN() est spécifique à l'implémentation, std::nan("1") produit un ensemble de bits. En ce qui concerne les informations que vous avez fournies, il ne devrait pas d'importance parce que vous devez utiliser is_nan() pour vérifier NaN de toute façon.
Juste un avertissement, vous souhaitez utiliser "calme" Nan, sinon le paramètre NaN pourrait soulever une exception de virgule flottante. Si vous ne savez pas si vous avez tranquille NaNs ou pas, alors vous ne devriez pas utiliser NaNs.
OriginalL'auteur jonas25007
Soit vous avez une valeur qui n'est pas juridique ou vous n'avez pas. Si vous avez une valeur qui n'est pas juridique (comme -1), l'utiliser comme une sentinelle. Si non, alors non. Utilisation Coup de pouce.En option ou rouler vos propres "valeur plus boolean" de la classe.
OriginalL'auteur David Schwartz
Vous ne pouvez pas. Je pense à deux autres façons:
std::unique_ptr<int>
comme c'est le C++11L'introduction de l'allocation dynamique où vous n'avez normalement pas besoin c'est probablement une mauvaise idée, au moins pour la performance.
Vrai, mais pour l'utiliser
int*
, vous devez maintenir une liste de tous les numéros utilisés, à garder vivant le pointeur.OriginalL'auteur Peter Pei Guo
Semble que vous allez avoir des problèmes plus loin en bas de la route. Le besoin de savoir comment beaucoup de valeurs sont valides sera arrosé par le biais de la base de code.
Je suggère d'avoir un usine et de la classe de base. Essentiellement, vous aurez au moins deux classes:
Lorsqu'une fonction exige explicitement les quatre valeurs, utilisez la
four_values
structure dans la déclaration. Sinon l'utilisation de latwo_values
structure dans la déclaration de la fonction.Cette relation indique qu'un
four_values
instance peut être utilisé dans une fonction nécessitant untwo_values
structure.Alternative
Une alternative est d'utiliser
std::vector
pour vos articles:Un avantage avec ce modèle est que les vecteurs peuvent vous dire combien d'objets il y a et le concept est évolutif, dans le cas où vous avez besoin de 6 éléments.
a1
est entaché de nullité, oua2
est entaché de nullité, mais pasb2
?OriginalL'auteur Thomas Matthews
0
,-1
,std::numeric_limits<int>::max()
. Lorsque vous traitez les données, utilisez uniquement la valeur si elle n'est pas égale à la valeur illégale (ou sentinelles).Comprennent un booléen indiquant le nombre de valeurs:
Utiliser un pointeur (
int*
oustd::unique_ptr<int>
comme par Peter @Guo Pei), et attribuernullptr
quand ils n'existent pas.OriginalL'auteur matsjoyce
Vous avez deux options pour éviter
boost::optional
et donc la dépendance à Boost:Utiliser le compilateur de
std::expérimental::optional
, qui est disponible à partir de GCC 4.9+ (et de Bruit dans les versions récentes IIRC) avec-std=c++14
.Utiliser la référence de "mise en œuvre" d'Andrzej Krzemieński pour
std::experimental::optional
de GitHub. C'est l'en-tête uniquement, de sorte que vous pouvez simplement copier l'en-tête de votre projet (bien sûr, en accordant une attention à la licence)OriginalL'auteur Daniel Frey
Alternativement, vous pouvez ajouter des membres à savoir s'il est normal de ses membres ont été touchés, quelque chose comme:
ou
OriginalL'auteur Jarod42
pour cela, Vous pouvez utiliser n'importe quel type de variable indiquant si deux ou quatre valeur sont affectés à ces variables.
Comme prendre un nom de variable attribuée = -1
Donc, si Votre valeur d'entrée sont positives, si deux valeurs sont à l'intérieur de fichier puis faites
a2 = b2 = assigend
Donc, lorsque Vous vérifiez ensuite il suffit de vérifier si la valeur de a2 et b2 sont -1 ou quelque chose d'autre,
OriginalL'auteur Robin Halder