首页 > 解决方案 > 方法调用/功能等效/最佳实践中的迭代器

问题描述

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

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

标签: c++iterator

解决方案


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是按值,并且您返回的是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是同一个std::array对象。


推荐阅读