Подтвердить что ты не робот

Пожалуйста, объясните этот код, который использует std:: ignore

Я читаю документацию на std::ignore из cppreference. Мне трудно понять истинную цель этого объекта, и примерный код не оправдывает этого. Например, в приведенном ниже коде, как и почему inserted установлено значение true? Мне это не имеет смысла.

#include <iostream>
#include <string>
#include <set>
#include <tuple>

int main()
{
    std::set<std::string> set_of_str;
    bool inserted;
    std::tie(std::ignore, inserted) = set_of_str.insert("Test");
    if (inserted) {
        std::cout << "Value was inserted sucessfully\n";
    }
}

Если кто-то может объяснить мне код, это будет оценено. Спасибо.

4b9b3361

Ответ 1

set::insert возвращает пару, где сначала находится итератор, к вставленному элементу, а второй - к bool, указав, был ли вставлен элемент.

std::tie создает кортеж ссылок lvalue. При присвоении результата из insert он позволяет вам установить переменные в tie в результаты вставки в членах return pair first и second.

std::ignore - это значение, которое может быть присвоено без эффекта.

В принципе, этот код игнорирует итератор для элемента, в который был вставлен "Test", и присваивает inserted члену second пары, возвращаемой set::insert, которая указывает, был ли вставлен элемент.

Ответ 2

Я думаю, что ответ Дэйва довольно хорош, но я хотел бы немного объяснить, зачем использовать такой подход.

В других языках, таких как Scala, Haskell или Python, у вас обычно есть кортежи (являющиеся парой кортежей из двух элементов), и у них есть этот идиоматический способ присвоить их переменным:

(var1,...,varN) = func_returning_tuple()

Это имеет целью расширить семантическое значение вашего кода и улучшить его читаемость, в противном случае у вас будет одна переменная без семантики для их элементов (например, t.first и т.д.), а в С++ - доступ к значениям кортежей, которые вы должны использовать:

varN = std::get<N>(my_tuple);

Итак, используя только галстук, вы можете упростить чтение кода примера следующим образом:

std::tie( element_iterator, inserted ) = set_of_str.insert("test");

И затем используйте ваши изолированные переменные по своему усмотрению, что улучшает поведение других (и даже самих себя) следующих операторов вашего кода.

std::ignore используется, когда вы не заботитесь о том, что возвращается, на некоторых других языках, у которых также есть этот ресурс, в Scala, например, это символ подчеркивания. Например, если я использую функцию insert в карте, и значение уже существует, оно просто возвращает пару, содержащую (iterator,false), поэтому, если я хочу, чтобы итератор для некоторого ключа, даже если мне все равно, если он уже существует на карте, Я могу сделать это с помощью этой строки:

std::tie( element_iterator, std::ignore ) = set_of_str.insert("test");

То, как С++ решает эту проблему с читабельностью кортежей и пар.