使用 post-increment 构造具有变量的整数 std::pair

Constructing std::pair of integers with a variable using post-increment

我尝试构造整数对,其中第二个整数大于第一个 1:

1 2
2 3
3 4

同时使用 std::make_pair 和构造函数,如下所示:

std::make_pair(n, n++);

但是,这会导致对反转:

2 1
3 2
4 3

如果我将 post 增量放在第一个参数上或使用 (n+1) 代替,我会得到所需的结果。

为什么会这样?

这与order of evaluation有关。来自 cppreference.com

Order of evaluation of any part of any expression, including order of evaluation of function arguments is unspecified. The compiler can evaluate operands and other subexpressions in any order, and may choose another order when the same expression is evaluated again.

因此无法保证是n还是n++先求值

来自 cppreference:

When calling a function (whether or not the function is inline, and whether or not explicit function call syntax is used), every value computation and side effect associated with any argument expression, or with the postfix expression designating the called function, is sequenced before execution of every expression or statement in the body of the called function.

所以这是怎么回事。

int n = 0;
auto p = std::make_pair( n, n++ );

首先我们判断make_pair的重载;我们得到:

make_pair<int&, int>( int&, int&& )

即,第一个参数是右值引用(最终绑定到 n),第二个参数是左值引用(最终绑定到 n++ returns).

我们评估 make_pair 的参数。它们以任意方式排序,但您会发现这里无关紧要。

n 绑定到 int& 不会复制值,它只是存储一个引用。

n++ 绑定到 int&& 创建一个临时对象,将 n 的值复制到其中,然后设置副作用以在之后增加 n

副作用何时发生是这里的关键。如上所述,它必须在调用函数 make_pair 之前的某个时间发生。

它可能发生在 n 为第一个参数求值之前,或之后;没关系,因为我们将 reference 绑定到 n 参数。然而,在 我们做 make_pair.

的主体之前,它被评估

所以在make_pair内,保证有对n的引用,其值为1,以及对临时值0的引用.然后它运行并 returns 与这些值配对。


看来您误解了 n++ 的意思 -- 它的意思是 "return the value of n, then afterwards increase it",它 不是 的意思 "return a value 1 bigger than n"。

你 return 比 n 大 1 的方式是 n+1