preincrement运算符的行为

时间:2015-10-25 06:15:28

标签: c++ runtime

请考虑以下代码:

#include <iostream>
#include <vector>
using namespace std;

int main(int argc, char **argv) {
  vector<int> v = { 1 };
  auto it = v.begin();
  cout << ++(*it) << " " << v[0] << " " << endl;
  cout << v[0] << endl;
  return EXIT_SUCCESS;
}

编译并运行时,此代码会生成以下控制台输出:

2 1 
2

鉴于++(*it)递增第一个向量值,我希望得到以下输出:

2 2 
2

为什么增量不会反映在cout的第一个v[0]语句中?

2 个答案:

答案 0 :(得分:2)

原因是:

cout<<++(*it);

正在打印下一个值2,但v的原始值仅在该行之后增加:

cout<<++(*it)<<" "<<v[0]<<" "; // v[0] is still `1`

现在值v[0]递增,结果为2

cout<< v[0]<<" ";

您可以在cout

之前递增
++(*it);
cout<<*it<<" "<<v[0]<<" ";

现在输出将是相同的。

答案 1 :(得分:1)

SMTP=smtp.gmail.com smtp_port=587 sendmail_from = gmailid@gmail.com sendmail_path = "\"C:\xampp\sendmail\sendmail.exe\" -t" [sendmail] smtp_server=smtp.gmail.com smtp_port=587 error_logfile=error.log debug_logfile=debug.log auth_username=gmailid@gmail.com auth_password=gmailpassword force_sender=my-gmailid@gmail.com 将递增并返回元素++(*it)引用,而不是迭代器本身,因此it在评估该表达式后为v[0]

那为什么不打印2? 因为222 s链实际上是嵌套函数调用,有点像这样:

operator<<

并感兴趣:

operator<<(operator<<(operator<<(operator<<(std::cout, ++(*it)), " "), v[0]), " ");

这是一个带有两个参数operator<<(operator<<(std::cout, ++(*it)), " "), v[0])operator<<(std::cout, ++(*it))的函数调用。 评估函数参数的顺序是未指定的,一个平台或编译器可能与另一个平台或编译器的执行方式不同(据我所知,从左到右和从右到左是常见的。)

如果首先评估第二个参数,则在保留v[0]的同时检索v[0],并打印1

如果首先评估第一个参数,则212首先发生,之后检索++(*it),因此我们打印v[0]

不幸的是,C ++标准只保证所有参数的评估在函数体之前进行排序,而不是相互关联。

在未排序的表达式中使用222v[0]可能会调用未定义的行为 - 这可能完全符合您的要求,或者发射导弹。