C ++通过非负位移移动范围?

时间:2018-01-07 08:21:24

标签: c++ c++11 move-semantics

我面临着需要将一系列元素向后移动一定(可能为零)的位移。为了说明,这里有一些代码:

std::vector<int> arr[4] = {{1}, {2}, {3}, {4}};
std::move(arr + 2, arr + 4, arr + 2 - k); // k can be either 0, 1, or 2,
// depending on how far much I want to move the elements

k非零时,这可以正常工作,但当k为零时失败(我希望当k = 0时移动成为无操作)。

以下代码在GCC中编译时会导致arr[2]arr[3]丢失所有元素:

int main() {
    std::vector<int> arr[4] = {{1}, {2}, {3}, {4}};
    std::move(arr + 2, arr + 4, arr + 2);
    for(int i = 0; i < 4; ++i) std::cout << arr[i].size() << ' '; // prints "1 1 0 0 "
    std::cout << std::endl;
}

C++ referencestd::move的目的地不应该在[first, last)范围内,我的代码违反了此规定。

经过一番挖掘后,我发现自动分配(即x = std::move(x)is not expected to be a no-op,这似乎就是为什么我不允许进行无操作范围{{1 }}

如果我想将一系列元素前进移动一定(可能是零)位移,也会发生此问题。

要解决此问题,我可以在移动之前明确检查std::move是非零的。但这是惯用的C ++方式吗?

1 个答案:

答案 0 :(得分:3)

是的,这样的检查非常典型。即使x [i] = x [i + 0];如果可能的话,您仍然希望跳过循环处理,这就是零位移检查将提供的内容。