Como inicializar o vetor de pares C ++ 17 com elemento opcional

34

No C ++ 17, como você declara e inicializa um vetor de pares (ou tuplas) com um elemento opcional?

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

Eu tenho um par em que o segundo elemento pode ser nulo / opcional.

Eugene
fonte
11
std::piecewise_constructtambém pode fornecer alternativas interessantes.
Marc Glisse 11/03
4
Isso responde sua pergunta? Como atribuir "nada" ao std :: optional <T>?
Julien Lopez
@JulienLopez Isso está falando sobre atribuição.
LF
@LF É a mesma pergunta quando você remove o contexto irrelevante: como você cria um opcional vazio?
Julien Lopez
11
@JulienLopez Em C ++, inicialização e atribuição são muito diferentes em geral. Só porque as duas perguntas têm soluções sobrepostas não significa que elas são iguais. Em particular, observe que você não deseja usar resetaqui.
LF

Respostas:

49

Você está procurando em std::nulloptvez de nullptr.

std::vector<std::pair<int, std::optional<bool> > > vec1 =
  { {1, true}, {2,false}, {3,std::nullopt} };
bitmask
fonte
3
(Vindo aqui do link de perguntas da rede quente) O código C ++ sempre é spam std::como este? Por que não apenas using std::vectore amigos, para que você pudesse escrever vector<pair<int, optional<bool>>? Lê com muito mais prudência
Alexander - Reinstate Monica
17
@ Alexander-ReinstateMonica "Lê com muito mais prudência" é subjetivo. O outro lado do argumento legibilidade é algo como isto: eu não quero ter que percorrer todo o caminho de volta para o topo do arquivo para descobrir qual especial vector , pair, optional, etc. Eu estou usando nesta linha. Incluir o espaço para nome inline me diz de forma inequívoca de onde vem essa função e o que ela faz; a linha é independente. Isso é especialmente verdadeiro para projetos maiores (pois evita completamente conflitos de espaço para nome), mas também é útil para exemplos concisos de código.
provavelmente_someone
3
@ Alexander-ReinstateMonica Essa lógica é boa se você tiver total supervisão e controle sobre qualquer código que use o código que você acabou de escrever (porque você saberá exatamente quando ocorre um "caso em que ocorrem colisões"). Mas se você estiver desenvolvendo algo como, por exemplo, desenvolver uma biblioteca ou uma API destinada ao uso por vários outros desenvolvedores, não poderá supervisionar todos os usos para descobrir se / quando ocorre uma colisão. Normalmente, é melhor nesse caso (relativamente comum) impedir as colisões, em vez de corrigi-las somente depois que alguém reclamar que seu produto está quebrado.
provavelmente_someone
3
@ Alexander-ReinstateMonica Qual dos seguintes itens você imediatamente percebe que é um nome de nível superior std? arg, count, find,size
LF
4
@ Alexander-ReinstateMonica, para mim, std::é totalmente discreto. Seria diferente se o nome do espaço para nome fosse muito maior.
Carsten S
24

Ou construção padrão de uso simples:

std::vector<std::pair<int, std::optional<bool>>> vec1 {
    {1, true}, {2,false}, {3,{}}
};
Marek R
fonte
6
Enquanto isso funciona, std::nulloptcomunica melhor a intenção.
Williham Totland