Как инициализировать вектор пар C ++ 17 с необязательным элементом

34

В C ++ 17, как вы объявляете и инициализируете вектор пар (или кортежей) с необязательным элементом?

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

У меня есть пара, где второй элемент может быть нулевым / необязательным.

Евгений
источник
1
std::piecewise_constructможет также предоставить интересные альтернативы.
Марк Глисс
4
Отвечает ли это на ваш вопрос? Как назначить «ничего» в std :: необязательный <T>?
Жюльен Лопес
@JulienLopez Это говорит о назначении.
LF
@LF При удалении ненужного контекста возникает тот же вопрос: как создать пустой необязательный параметр?
Жюльен Лопес
1
@JulienLopez В C ++ инициализация и присваивание в целом сильно различаются. Тот факт, что два вопроса имеют перекрывающиеся решения, не означает, что они совпадают. В частности, обратите внимание, что вы не хотите использовать resetздесь.
LF

Ответы:

49

Вы ищете std::nulloptвместо nullptr.

std::vector<std::pair<int, std::optional<bool> > > vec1 =
  { {1, true}, {2,false}, {3,std::nullopt} };
битовая
источник
3
(Исходя из ссылки на горячие сетевые вопросы) Всегда ли спам-код на C ++ выглядит std::следующим образом? Почему бы не просто using std::vectorи друзьям, чтобы вы могли просто написать vector<pair<int, optional<bool>>? Читает намного более разумно
Александр - Восстановить Монику
17
@ Alexander-ReinstateMonica "Читает более разумно" субъективно. Оборотная сторона читаемости аргумент что - то вроде этого: Я не хочу , чтобы пройти весь путь обратно в верхней части файла , чтобы выяснить , какие именно vector , pair, optionalи т.д. , я использую в этой строке. Включение встроенного пространства имен однозначно говорит мне, откуда взялась эта функция и что она делает; линия автономна. Это особенно верно для больших проектов (так как оно полностью избегает конфликтов пространства имен), но также полезно для кратких примеров кода.
вероятно, кто-то
3
@ Alexander-ReinstateMonica Эта логика хороша, если у вас есть полный контроль и контроль над любым кодом, который использует код, который вы только что написали (потому что тогда вы точно знаете, когда происходит «отключенный случай, в котором происходят столкновения»). Но если вы делаете что-то вроде, например, разработки библиотеки или API, который предназначен для использования группой других разработчиков, вы не можете контролировать каждое отдельное использование, чтобы выяснить, происходит ли когда-либо такое столкновение. В этом (относительно распространенном) случае лучше предотвращать столкновения, а не исправлять их только после того, как кто-то пожаловался на неисправность вашего продукта.
вероятно, кто-то
3
@ Alexander-ReinstateMonica Что из следующего вы сразу понимаете, это имя верхнего уровня std? arg, count, find,size
LF
4
@ Alexander-ReinstateMonica, для меня, std::абсолютно ненавязчиво. Было бы иначе, если бы имя пространства имен было намного длиннее.
Карстен С
24

Или просто используйте конструкцию по умолчанию:

std::vector<std::pair<int, std::optional<bool>>> vec1 {
    {1, true}, {2,false}, {3,{}}
};
Марек Р
источник
6
Пока это работает, std::nulloptлучше сообщает намерение.
Виллихам Тотланд