为什么所有列表都被填充 [英] Why Are All List's Being Populated

查看:200
本文介绍了为什么所有列表都被填充的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以给定定义:

typedef char Task;

struct Tache {
    char step;
    int duration;
    list<Task> precedentTask;
};

我为 Tache写了一个提取运算符

istream& operator>>(istream& lhs, Tache& rhs) {
    string line;

    getline(lhs, line, '\n');

    stringstream ss(line);

    ss >> rhs.step;
    ss.ignore(numeric_limits<streamsize>::max(), '(');
    ss >> rhs.duration;
    ss.ignore(numeric_limits<streamsize>::max(), ')');

    const regex re("\\s*,\\s*([a-zA-Z])");
    string precedentTasks;

    getline(ss, precedentTasks);

    transform(sregex_token_iterator(cbegin(precedentTasks), cend(precedentTasks), re, 1), sregex_token_iterator(), back_insert_iterator<list<Task>>(rhs.precedentTask), [](const string& i) {
        return i.front();
    });

    return lhs;
}

但是当我尝试使用这个提取操作符和 istream_iterator precedentTask 成员似乎渗入下一个元素。例如,给定:

However when I try to use this extraction operator with an istream_iterator the precedentTask member seems to bleed into the next element. For example, given:

stringstream seq("A(3)\nB(4),A\nC(2),A\nE(5),A\nG(3),A\nJ(8),B,H\nH(7),C,E,G\nI(6),G\nF(5),H");

list<Tache> allTaches{ istream_iterator<Tache>(seq), istream_iterator<Tache>() };

for (const auto& i : allTaches) {
    cout << i.step << ' ' << i.duration << ' ';
    copy(cbegin(i.precedentTask), cend(i.precedentTask), ostream_iterator<Task>(cout, " "));
    cout << endl;
}

生活示例

Live Example

我得到:

A 3

B 4 A

C 2 AA

E 5 AAA

G 3 AAAA

J 8 AAAABH

H 7 AAAABHCEG

I 6 AAAABHCEGG

F 5 AAAABHCEGGH

A 3
B 4 A
C 2 A A
E 5 A A A
G 3 A A A A
J 8 A A A A B H
H 7 A A A A B H C E G
I 6 A A A A B H C E G G
F 5 A A A A B H C E G G H

而不是我的预期:


A 3

B 4 A

C 2 A

E 5 A

G 3 A

J 8 BH

H 7 CEG

I 6 G

F 5 H

A 3
B 4 A
C 2 A
E 5 A
G 3 A
J 8 B H
H 7 C E G
I 6 G
F 5 H

我滥用 sregex_token_iterator

推荐答案

做正则表达式和一切与 istream_iterator 在底层做什么:它只有一个 T 元素,它会当您增加它时读入:

This has nothing to do with regex and everything to do with what istream_iterator does under the hood: it only has one T element that it will read into when you increment it:


istream_iterator& operator ++();

3 需要 in_stream!= 0

4 效果 * in_stream>>值

5 返回 * this

您的流运算符只是附加到 rhs.precedentTask ,但它不一定为空。只是先清除它。这不是 istream_iterator 问题,您的 operator>> 也必须能够在这种情况下工作:

Your stream operator is just appending to rhs.precedentTask, but it's not necessarily empty to start with. Just clear it first. This isn't an istream_iterator problem either, your operator>> has to be able to work in this situation too:

Tache foo;
while (std::cin >> foo) {
    // ...
}

如果你所做的是追加,那么在第一个之后的每个后续 Tache 。你完全负责初始化对象的所有成员,你不应该假设它们以前的值。

If all you're doing is appending, then every subsequent Tache after the first one will be wrong. You are completely responsible for initializing all of the members of the object and you should make no assumptions about their previous values.

我建议用 transform()一个循环:

sregex_token_iterator it(cbegin(precedentTasks), cend(precedentTasks), re, 1), end;
for (; it != end; ++it) {
    rhs.precedentTask.push_back(it->front());
}

或包装在范围内:

for (std::string match : sregex_matches(precedentTasks, re, 1)) {
    rhs.precedentTask.push_back(match.front());
}

这篇关于为什么所有列表都被填充的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆