C++ 输入流:Solaris 与 Linux 中的操作顺序
C++ Input stream: operation order in Solaris vs. Linux
我有一个非常简单的测试程序,它使用 istringstreams 从 std::string 中读取整数。代码是:
std::map<int, int> imap;
int idx, value;
std::string str("1 2 3 4 5 6 7 8");
istringstream is(str);
while(is >> idx >> imap[idx]){
cout << idx << " " << imap[idx] << endl;
}
cout << endl;
std::map<int, int>::iterator itr;
for(itr = imap.begin(); itr != imap.end(); itr++){
cout << itr->first << " " << itr->second << endl;
}
当我在 Solaris 10 上 运行 时,它会产生以下输出:
1 2
3 4
5 6
7 8
1 2
3 4
5 6
7 8
然而,当我在 CentOS 7 下 运行 它时,我得到:
1 0
3 0
5 0
7 0
1 4
3 6
5 8
7 0
4204240 2
有谁知道为什么在 Linux 下与在 Solaris 下会有所不同?它显然是在读入地图索引之前将值读入地图,但我不知道为什么。我可以通过稍微更改代码使其在 Linux 下工作:
std::map<int, int> imap;
int idx, value;
std::string str("1 2 3 4 5 6 7 8");
istringstream is(str);
while(is >> idx >> value){
imap[idx] = value;
cout << idx << " " << imap[idx] << endl;
}
std::map<int, int>::iterator itr;
for(itr = imap.begin(); itr != imap.end(); itr++){
cout << itr->first << " " << itr->second << endl;
}
我知道这是一个有效的修复,但我周围的人想知道它为什么不同。我们正在从 Solaris 迁移到 Linux,当这样的事情出现时,他们想知道为什么。不知道为什么,求指教
is >> idx >> imap[idx]
这个表达式等同于
operator>>(operator>>(is, idx), imap.operator[](idx))
同一函数的参数求值相对于彼此是无序的; operator>>(is, idx)
或 imap.operator[](idx)
可能首先被计算(也就是说,is >> idx
或 imap[idx]
可能首先被计算)。如果先评估后者,则结果是一个左值,指的是地图中 idx
的 old 值对应的值;第二次读取将覆盖此值,而不是 idx
.
的 new 值对应的值
修改后的代码通过确保在访问 imap[idx]
之前读取 idx
来修复此问题。
我有一个非常简单的测试程序,它使用 istringstreams 从 std::string 中读取整数。代码是:
std::map<int, int> imap;
int idx, value;
std::string str("1 2 3 4 5 6 7 8");
istringstream is(str);
while(is >> idx >> imap[idx]){
cout << idx << " " << imap[idx] << endl;
}
cout << endl;
std::map<int, int>::iterator itr;
for(itr = imap.begin(); itr != imap.end(); itr++){
cout << itr->first << " " << itr->second << endl;
}
当我在 Solaris 10 上 运行 时,它会产生以下输出:
1 2
3 4
5 6
7 8
1 2
3 4
5 6
7 8
然而,当我在 CentOS 7 下 运行 它时,我得到:
1 0
3 0
5 0
7 0
1 4
3 6
5 8
7 0
4204240 2
有谁知道为什么在 Linux 下与在 Solaris 下会有所不同?它显然是在读入地图索引之前将值读入地图,但我不知道为什么。我可以通过稍微更改代码使其在 Linux 下工作:
std::map<int, int> imap;
int idx, value;
std::string str("1 2 3 4 5 6 7 8");
istringstream is(str);
while(is >> idx >> value){
imap[idx] = value;
cout << idx << " " << imap[idx] << endl;
}
std::map<int, int>::iterator itr;
for(itr = imap.begin(); itr != imap.end(); itr++){
cout << itr->first << " " << itr->second << endl;
}
我知道这是一个有效的修复,但我周围的人想知道它为什么不同。我们正在从 Solaris 迁移到 Linux,当这样的事情出现时,他们想知道为什么。不知道为什么,求指教
is >> idx >> imap[idx]
这个表达式等同于
operator>>(operator>>(is, idx), imap.operator[](idx))
同一函数的参数求值相对于彼此是无序的; operator>>(is, idx)
或 imap.operator[](idx)
可能首先被计算(也就是说,is >> idx
或 imap[idx]
可能首先被计算)。如果先评估后者,则结果是一个左值,指的是地图中 idx
的 old 值对应的值;第二次读取将覆盖此值,而不是 idx
.
修改后的代码通过确保在访问 imap[idx]
之前读取 idx
来修复此问题。