为什么所有列表都被填充 [英] Why Are All List's Being Populated
问题描述
所以给定定义:
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屋!