使用移动语义的初始化列表顺序中的未定义行为

Undefined behaviour in initializer list order using move semantics

是 (1) 未定义的行为,还是总是先评估对中的第一个元素?

#include <array>
#include <utility>

int bar(std::array<int, 3>&& ) {
    return 1;
}

std::pair<std::array<int, 3>, int> foo() {
    std::array<int, 3> a;
    return { a, bar(std::move(a)) };  // (1)
}

附带说明一下,使用 return make_pair(a, bar(std::move(a))); 会有所不同吗?

您可能会看到 evaluation order 的规则。

10) In list-initialization, every value computation and side effect of a given initializer clause is sequenced before every value computation and side effect associated with any initializer clause that follows it in the brace-enclosed comma-separated list of initializers.

所以

return { a, bar(std::move(a)) };

a 先求值,然后 bar(std::move(a)).

As a side note, would using return make_pair(a, bar(std::move(a))); instead be different?

是的,这是一个函数调用,未指定求值顺序。它本身不是 UB,但如果一个订单导致 UB,则可能导致 UB。 在您的情况下,两个订单都很好并且给出相同的结果。

C++17 还增加了该限制:

15) In a function call, value computations and side effects of the initialization of every parameter are indeterminately sequenced with respect to value computations and side effects of any other parameter.