请解释使用std::ignore的这段代码。

27
我正在阅读来自cppreference的std::ignore文档。我发现很难理解这个对象的真正目的,而且示例代码也没有很好地说明问题。例如,在下面的代码中,如何以及为什么将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";
    }
}

如果有人能够向我解释这段代码,我将不胜感激。谢谢。


5
你理解 std::tie 的作用以及 std::set::insert 返回的是什么吗? - Xymostech
2
@bames53 bool inserted = set_of_str.insert("测试").second; - David
10
忽略那些戴着标准领带的家伙,std::ignore - sbi
std::ignore 在任何方面都是“神奇”的吗?使用 std::ignore 而不是命名但未使用的变量,编译器是否会进行更好的优化? - Mike Elkins
1
@MikeElkins 可能不是,但这可以节省代码并更清晰地使用 std::ignore。 - David
显示剩余2条评论
2个回答

41

set::insert返回一对数值,第一个是指向插入元素的迭代器,第二个是一个布尔值,表示元素是否已插入。

std::tie创建了一组左值引用的元组。当对 insert 返回的结果进行赋值时,可以使用 tie 中的变量将插入的结果分别赋给返回 pairfirstsecond 成员。

std::ignore 是一个不产生任何影响的值。

因此,这段代码忽略了插入 "Test" 元素的迭代器,并将 inserted 赋值为 set::insert 返回的一对数值中指示元素是否已插入的 second 成员。


19

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

在其他语言中,比如Scala、Haskell 或 Python,通常会存在元组 (pair 是一个由两个元素组成的元组) 并且它们有一种惯用的方式将它们赋值给变量:

(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中的下划线。例如,如果我在映射中使用插入函数并且该值已存在,则它只会返回包含 (iterator,false) 的对,因此即使我不关心它是否已经存在于映射中,我也可以使用以下行获取某个键的迭代器:

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接