【问题标题】:return value std::mismatch for equal vectors相等向量的返回值 std::mismatch
【发布时间】:2017-02-21 11:38:19
【问题描述】:

我正在使用std::mismatch 来检查两个结构向量是否完全相同。通常,在我的程序中,它们不是,但在特殊情况下可能会发生。在documentation 我发现以下内容:

“如果两个序列中比较的元素都匹配,则函数返回一个对,其中第一个设置为last1,第二个设置为第二个序列中相同相对位置的元素。”

但是,如果我创建两个完全相等的向量,std::mismatch 不会返回值。我正在尝试做的一个小例子:

#include <vector>
#include <algorithm>
#include <utility>

struct structwithnumber {
    int id;
};

bool compare_structs (structwithnumber* struct1, structwithnumber* struct2) {
    return struct1->id == struct2->id;
};

bool compare_structvectors(std::vector<structwithnumber*> v1, std::vector<structwithnumber*> v2) {
    if (v1.size() != v2.size())
    {
        return false;
    }
    std::pair<std::vector<structwithnumber*>::iterator, std::vector<structwithnumber*>::iterator> mypair;
    mypair = std::mismatch(v1.begin(), v1.end(), v2.begin(), compare_structs);
    return (compare_structs(*mypair.first, *mypair.second));
}

void simple_example() {
    structwithnumber* struct1 = new structwithnumber();
    structwithnumber* struct2 = new structwithnumber();
    struct1->id = 1;
    struct2->id = 2;
    std::vector<structwithnumber*> v1;
    std::vector<structwithnumber*> v2;
    v1.push_back(struct1);
    v1.push_back(struct2);
    v2.push_back(struct1);
    v2.push_back(struct2);
    compare_structvectors(v1, v2);
}

当我在 Visual Studios 15 中运行此代码时,我收到一条错误消息:

 return (compare_structs(*mypair.first, *mypair.second));

经过进一步调查,结果发现 mypair 在不匹配后仍然为空。从文档中,我虽然这将返回每个向量的最后一个值。我是否误解了当出现 2 个所有元素都匹配的序列时不匹配的表现?

【问题讨论】:

  • “我遇到了一个错误”——您愿意与您的听众分享该错误的性质吗? (从“输出”窗口复制和粘贴。)
  • here 是一个更可靠的参考网站。

标签: c++ c++11 stl


【解决方案1】:

std::mismatch,如果一切都匹配,则返回一个(至少一个)结束后迭代器。您不能像在 compare_structs(*mypair.first, *mypair.second) 中那样取消引用它。

代码应按如下方式测试案例:

mypair = std::mismatch(v1.begin(), v1.end(), v2.begin(), compare_structs);

if(mypair.first == v1.end()) {
    // No mismatch, do something sensible
} else {
    return (compare_structs(*mypair.first, *mypair.second));
}

【讨论】:

  • 谢谢。我将其更改为:mypair = std::mismatch(v1.begin(), v1.end(), v2.begin(), compare_structs);返回 (mypair.first == v1.end());因为第二个陈述总是错误的。
  • 总是依赖于 "mypair.first == v1.end()" 自 c++14 以来可能是错误的。文档说“当比较到达 last1 或 last2 时,没有发现不匹配,以先发生者为准,该对包含结束迭代器和来自另一个范围的相应迭代器”
  • @AnandShah 用于具有两个末端迭代器的重载,而 OP 的代码中只有一个。我不确定为什么删除了关于 UB 的注释,因为如果第二个范围比第一个短,这是唯一可能的结果。
【解决方案2】:

但是,如果我创建两个完全相等的向量,std::mismatch 不会返回值

当然可以,它必须返回一些东西

经过进一步调查,结果发现 mypair 在不匹配后仍然为空。

这是什么意思? mypair empty 怎么样?它是一对,它在创建时正好有两个成员,在调用mismatch 之后仍然有两个成员。

但是,当两个序列匹配时,它是一对 end 迭代器。 这就像说您有一对空的不匹配序列(这仍然与不可能的空对相同)。

您不能取消对这些迭代器的引用,因此这样做的代码会损坏。您需要在取消引用之前进行测试:

const bool v1_mismatch = (mypair.first != v1.end());
const bool v2_mismatch = (mypair.second != v2.end());
const bool identical = !(v1_mismatch || v2_mismatch);

if (v1_mismatch && v2_mismatch) {
    // this is the only case where you can dereference both
    return compare_structs(*mypair.first, *mypair.second);
}
// otherwise you can dereference at most one iterator,
// and if v1,v2 are identical, you can't dereference either

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-15
    • 2014-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多