这是Minimal, Complete, Verifiable Example我明白这不是copacetic。无论如何,给出结构:
UIViewController
我可以做以下事情:
presentViewController(_:animated:)
然而,这给了我结果:
-1215720516 1
2 1
2 3
4 3
4 5
6 5
6 7
8 7
8 9
0 9
要初始化struct Foo {
int even;
int odd;
};
istream& operator>>(istream& lhs, Foo& rhs) {
int input;
lhs >> input;
(input % 2 == 0 ? rhs.even : rhs.odd) = input;
return lhs;
}
,我可以编写代码:
stringstream bar("1 2 3 4 5 6 7 8 9 0");
for (const auto& i : vector<Foo>{istream_iterator<Foo>(bar), istream_iterator<Foo>()}) {
cout << i.even << ' ' << i.odd << endl;
}
这给出了我的预期结果:
0 1
2 0
0 3
4 0
0 5
6 0
0 7
8 0
0 9
0 0
我知道有一个不完全覆盖变量的提取运算符是粗略的。这最初源于我的回答here和我的问题here,在我看来,它更自然地期望对读取之间的变量进行零初始化。在任何情况下,是否可以使用Foo
使得变量在读取之间进行零初始化,或者我必须使用for(Foo i{}; bar >> i; i = Foo{}) {
cout << i.even << ' ' << i.odd << endl;
}
- 循环吗?
答案 0 :(得分:2)
在我的脑海中有一个更自然的期望,即在读取之间对变量进行零初始化
这是一个不正确的期望。 operator>>
应完全且完全负责初始化对象。您不能假设该对象先前已默认/值初始化。一个非常标准的用例是读取while循环中的所有对象:
Foo foo;
while (std::cin >> foo) { ... }
第二次通过,foo
将具有旧的价值 - 这里没有任何归零。因此,您需要确保在操作员返回时,新对象完全由您设置。
最简单的方法是首先对其进行初始化:
istream& operator>>(istream& lhs, Foo& rhs) {
int input;
lhs >> input;
rhs = Foo{}; // <== add this
input % 2 == 0 ? rhs.even : rhs.odd) = input;
return lhs;
}
或者你可以手动写两个:
if (input % 2 == 0) {
rhs.odd = 0;
rhs.even = input;
}
else {
rhs.odd = input;
rhs.even = 0;
}
或聚合初始化每个案例:
rhs = input % 2 == 0 ? Foo{input, 0} : Foo{0, input};
无论如何,operator>>
负责将您想要归零的值归零。
答案 1 :(得分:1)
是否可以使用istream_iterator使得变量在读取之间进行零初始化?
如果您查看internals of the istream_iterator,它会有以下内部状态。
private:
istream_type* _M_stream;
_Tp _M_value;
bool _M_ok;
默认构造_M_value的位置。
当它使用++ / ++时,它调用_M_read(),它的实现中有以下相关的行。
*_M_stream >> _M_value;
因此迭代器本身永远不会在你的extrator之外触及你的Foo的状态,并且_M_value
在调用之间被重用。即你需要自己以某种方式初始化它。我认为operator>>
是一个合理的地方。