使用后增量构造带有变量的 std::pair 整数

Pes*_*o_T 8 c++ function function-parameter post-increment std-pair

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

1 2
2 3
3 4
Run Code Online (Sandbox Code Playgroud)

std::make_pair像这样使用两者和构造函数:

std::make_pair(n, n++);
Run Code Online (Sandbox Code Playgroud)

但是,这会导致对相反:

2 1
3 2
4 3
Run Code Online (Sandbox Code Playgroud)

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

为什么会这样?

JeJ*_*eJo 6

这与求值顺序有关。来自cppreference.com

任何表达式的任何部分的求值 顺序,包括函数参数求值顺序 是未指定的。编译器可以以任何顺序 计算操作数和其他子表达式,并且可以在再次计算相同表达式时选择其他顺序

因此,不能保证nn++先评估。

  • 对不起,小孩子跳到我身上了。`make_pair<int&, int>(int&, int&&)` -- 第二个参数是一个右值,所以你得到一个副本;第一个参数是参考。所以真正的问题是,参数评估的副作用相对于函数调用是如何排序的?它们之间的相对顺序如何并不那么重要。`n++` 的副作用是在函数调用之前、之后评估的,还是不按顺序排列的?这个问题与您的答案略有不同。 (2认同)

Yak*_*ont 6

cppreference

调用函数时(无论该函数是否内联,以及是否使用显式函数调用语法),与任何参数表达式或指定被调用函数的后缀表达式相关的每个值计算和副作用都排在前面执行被调用函数体中的每个表达式或语句。

所以这里发生的事情是这样的。

int n = 0;
auto p = std::make_pair( n, n++ );
Run Code Online (Sandbox Code Playgroud)

首先我们确定make_pair;的重载 我们得到:

make_pair<int&, int>( int&, int&& )
Run Code Online (Sandbox Code Playgroud)

即,第一个参数是右值引用(最终绑定到n),第二个参数是左值引用(最终绑定到n++返回的临时对象)。

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

绑定nint&不复制值,它只是存储一个引用。

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

什么时候出现副作用是这里的关键。如上所述,它必须在make_pair调用函数之前发生。

它可能发生在n为第一个参数求值之前或之后;不要紧,因为我们是有约束力的基准n给个说法。但是,我们执行make_pair.

所以在里面make_pair,它保证有一个引用n,其值为1,以及一个临时引用,其值为0。然后运行并返回具有这些值的一对。


看来你误解了什么n++意思——它的意思是“返回 的值n,然后增加它”,而不是“返回一个大于 1 的值n”。

返回值 1 大于nis 的方式n+1

  • 那么 `std::make_pair(n++, n)` 能保证OP想要的结果吗? (3认同)