方法调用中的迭代器/功能等价/最佳实践

Iterators in Method call / Functional Equivalence / Best Practise

关于编译器如何计算某些东西的快速问题。在下面的代码中,我想知道我写的是不是一个好主意,或者我是否应该更明确。

constexpr auto Checksum = [](const std::vector<uint8_t>& values) -> std::array<uint8_t, 6> {
  std::vector<uint8_t> data{ 0x03, 0x03, 0x00, 0x17, 0x13 };
  data.insert(data.end(), values.begin(), values.end());
  data.resize(data.size() + 6);
  uint32_t c = 1;
  for (const auto v_i : data)
  {
    uint8_t c0 = c >> 25;
    c = ((c & 0x1ffffff) << 5) ^ v_i;
    if (c0 & 1)
      c ^= 0x3b6a57b2;
    if (c0 & 2)
      c ^= 0x26508e6d;
    if (c0 & 4)
      c ^= 0x1ea119fa;
    if (c0 & 8)
      c ^= 0x3d4233dd;
    if (c0 & 16)
      c ^= 0x2a1462b3;
  }
  c ^= 0x2bc830a3;
  std::array<uint8_t, 6> ret;
  for (size_t i = 0; i < 6; i++)
    ret[i] = (c >> (5 * (5 - i))) & 31;
  return ret;
};

std::vector<uint8_t> data = ConvertBits();
data.insert(data.end(), Checksum(data).begin(), Checksum(data).end());   //  <------------ What is happening here?

显然 .insert() 的参数保证在使用前完全构建,但是迭代器是在一个不可见的临时对象上工作吗?我应该更明确地做:

std::array<uint8_t, 6> temp = Checksum(data);
data.insert(data.end(), temp.begin(), temp.end());

上述代码和直接在 .insert() 方法中使用迭代器在功能上是否等同?

constexpr auto Checksum = [](const std::vector<uint8_t>& values) -> std::array<uint8_t, 6> 
{
    //...
    std::array<uint8_t, 6> ret;
    //...
    return ret;
}
//...
data.insert(data.end(), Checksum(data).begin(), Checksum(data).end());

data.insert 调用未定义的行为,因为 Checksum(data).begin()Checksum(data).end() 是两个完全不同的 std::array 容器的迭代器。

Checksum 的 return 语义是按值的,您正在 returning std::array<uint8_t, 6>。如果您 return 引用相同的 std::array<uint8_t, 6>,那么该行将是可行的。

另一方面,这段代码:

std::array<uint8_t, 6> temp = Checksum(data);
data.insert(data.end(), temp.begin(), temp.end());

可以安全使用,因为 temp 是同一个 std::array 对象。