Comment initialiser un vecteur de paires C ++ 17 avec un élément facultatif

34

En C ++ 17, comment déclarer et initialiser un vecteur de paires (ou tuples) avec un élément optionnel?

    std::vector<std::pair<int, optional<bool> > > vec1 = { {1, true},
                                                           {2, false}, 
                                                           {3, nullptr}};

J'ai une paire où le deuxième élément peut être nul / facultatif.

Eugène
la source
1
std::piecewise_constructpeut également fournir des alternatives intéressantes.
Marc Glisse
4
Est-ce que cela répond à votre question? Comment assigner "rien" à std :: optional <T>?
Julien Lopez
@JulienLopez Cela parle d'affectation.
LF
@LF C'est la même question lorsque vous supprimez le contexte non pertinent: comment créer une option vide?
Julien Lopez
1
@JulienLopez En C ++, l'initialisation et l'affectation sont très différentes en général. Ce n'est pas parce que les deux questions ont des solutions qui se chevauchent qu'elles sont identiques. Notez en particulier que vous ne souhaitez pas l'utiliser resetici.
LF

Réponses:

49

Vous recherchez au std::nulloptlieu de nullptr.

std::vector<std::pair<int, std::optional<bool> > > vec1 =
  { {1, true}, {2,false}, {3,std::nullopt} };
bitmask
la source
3
(En venant ici à partir du lien des questions réseau chaudes) Le code C ++ est-il toujours du spam std::comme ça? Pourquoi pas juste using std::vectoret amis, pour que vous puissiez simplement écrire vector<pair<int, optional<bool>>? Lit plus sainement
Alexander - Rétablit Monica
17
@ Alexander-ReinstateMonica "Lit plus sainement" est subjectif. Le revers de l'argument de la lisibilité est quelque chose comme ceci: Je ne veux pas avoir à aller le dos de chemin vers le haut du fichier pour savoir qui notamment vector , pair, optional, etc. J'utilise dans cette ligne. L'inclusion de l'espace de noms en ligne me dit sans ambiguïté d'où vient cette fonction et ce qu'elle fait; la ligne est autonome. Cela est particulièrement vrai pour les grands projets (car il évite complètement les conflits d'espace de noms), mais également utile pour des exemples de code concis.
probablement_someone
3
@ Alexander-ReinstateMonica Cette logique est très bien si vous avez une supervision et un contrôle complets sur tout code qui utilise le code que vous venez d'écrire (car alors vous savez précisément quand un "cas dans lequel des collisions se produisent" se produit). Mais si vous faites quelque chose comme, par exemple, le développement d'une bibliothèque ou d'une API destinée à un tas d'autres développeurs, vous ne pouvez pas superviser chaque utilisation pour déterminer si / quand une telle collision se produit. Il est généralement préférable dans ce cas (relativement courant) de prévenir les collisions, plutôt que de les corriger uniquement après que quelqu'un se soit plaint que votre produit est en panne.
probablement_someone
3
@ Alexander-ReinstateMonica Lequel des éléments suivants réalisez-vous immédiatement est un nom de haut niveau std? arg, count, find,size
LF
4
@ Alexander-ReinstateMonica, pour moi, std::est totalement discret. Ce serait différent si le nom de l'espace de noms était beaucoup plus long.
Carsten S
24

Ou construction simple par défaut:

std::vector<std::pair<int, std::optional<bool>>> vec1 {
    {1, true}, {2,false}, {3,{}}
};
Marek R
la source
6
Pendant que cela fonctionne, std::nulloptmieux communique l'intention.
Williham Totland