c ++列表在设置差异后不调整大小

Jos*_*ays 5 c++ set-difference

考虑以下代码:

#include <algorithm>
#include <iostream>
#include <list>

int main() {
    std::list<int> v = {1, 3, 4};
    std::cout << v.size() << std::endl;
    v.resize(0);
    std::cout << v.size() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

编译输出后,如预期的那样,是

3
0
Run Code Online (Sandbox Code Playgroud)

现在我添加一组差异。

#include <algorithm>
#include <iostream>
#include <list>

int main() {
    std::list<int> x = {1, 3, 4};
    std::list<int> y = {1, 2, 3, 5};
    std::list<int> v;
    x.sort();
    y.sort();
    std::cout << v.size() << std::endl;
    auto it =
        std::set_difference(x.begin(), x.end(), y.begin(), y.end(), v.begin());
    std::cout << v.size() << std::endl;
    v.resize(0);
    std::cout << v.size() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

输出是

0
4
4
Run Code Online (Sandbox Code Playgroud)

为什么调整大小适用于第一个示例,但不适用于第二个示例?

Sam*_*hik 8

这是因为它是未定义的行为。

to的最后一个参数std::set_difference是一个输出迭代器。你正在通过v.begin()

这将返回一个指向空列表开头的指针。为了让您想要的代码像宣传的那样*iter++工作,输出迭代器的操作必须向 list 添加新值

不幸的是,无论您对 返回的迭代器做begin()什么,您对它所做的任何事情都不会使列表比原来更大或更小。它只是迭代列表的现有内容

在这一点上,您几乎处于未定义的行为领域,您得到的任何结果都将是完全荒谬的(如果不是立即崩溃)。

除了传递的v.begin(),您需要使用std::back_insert_iterator代替

  • 有 `std::back_inserter` 可以简化使用 `std::back_insert_iterator`。你可以用 `std::back_inserter(v)` 替换 `v.begin()`。 (2认同)