27

我正在阅读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";
    }
}

如果有人可以向我解释代码,将不胜感激。谢谢。

4

2 回答 2

41

set::insert返回一对,其中 first 是插入元素的迭代器, second 是一个布尔值,表示该元素是否被插入。

std::tie创建一个左值引用的元组。当从它分配给结果时insert,您可以将 中的变量设置为在 return和成员tie中插入的结果pairfirstsecond

std::ignore是一个可以赋值但没有效果的值。

所以基本上,这段代码忽略了"Test"插入元素的迭代器,并分配insertedsecond返回的对的成员set::insert,指示是否插入了一个元素。

于 2013-04-26T01:43:00.310 回答
19

我认为戴夫的回答很好,但我想解释一下为什么要使用这种方法。

在 Scala、Haskell 或 Python 等其他语言中,通常存在元组(将两个元素的元组配对),并且它们具有将它们分配给变量的惯用方式:

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

这旨在扩展代码的语义值并提高其可读性,否则您将拥有一个对其元素没有语义的单个变量(如 t.first 等),并在 C++ 中访问您的元组值将不得不使用:

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

因此,仅使用 tie,您可以使示例代码更易于阅读,如下所示:

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

然后随意使用您的隔离变量,这改善了其他人(甚至您自己)阅读代码下一条语句的方式。

std::ignore您不关心返回的内容时使用,在其他一些语言中您也有此资源,例如在 Scala 中,这是下划线。例如,如果我在 map 中使用 insert 函数并且值已经存在,它只返回包含(iterator,false)so 如果我想要某个键的迭代器的对,即使我不在乎它是否已经存在于 map 中,我也可以用这条线做:

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

这就是 C++ 解决元组和对的可读性问题的方式。

于 2013-05-02T22:31:29.977 回答