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

问题描述

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

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() 方法中直接使用迭代器在功能上是否等效?

解决方法

const pos_products = await db.pos_products.get({id: idProduct});
console.log(pos_products.value);
//OR
const { value: pos_products } = await db.pos_products.get({id: idProduct});
console.log(pos_products);

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.insertChecksum(data).begin() 是两个完全不同的 Checksum(data).end() 容器的迭代器。

std::array 的返回语义是按值,而您返回的是 Checksum。如果您返回对同一个 std::array<uint8_t,6> 的引用,那么该行将是可行的。

另一方面,这段代码:

std::array<uint8_t,6>

使用起来是安全的,因为 std::array<uint8_t,6> temp = Checksum(data); data.insert(data.end(),temp.begin(),temp.end()); 是同一个 temp 对象。