智能指针操作符[]"不匹配"当type是具有已知长度的数组时

时间:2017-08-12 20:09:05

标签: c++11 smart-pointers

鉴于以下代码:

typedef std::unique_ptr<uint8_t[SHA256::DIGEST_SIZE]> sha256hash;

std::ostream& operator<<(std::ostream& os, const sha256hash &hash) {
    // Save old formatting
    std::ios oldFormat(nullptr);
    oldFormat.copyfmt(os);

    // Set up formatting
    os << std::setfill('0') << std::setw(2) << std::hex;

    // Do our printing
    for (int i = 0;i < SHA256::DIGEST_SIZE; i++)
      os << hash[i];

    // Restore formatting
    os.copyfmt(oldFormat);
}

我收到以下错误:

In function ‘std::ostream& operator<<(std::ostream&, const sha256hash&)’:
error: no match for ‘operator[]’ (operand types are ‘const sha256hash {aka const std::unique_ptr<unsigned char [32]>}’ and ‘int’)
   os << hash[i];

我认为typedef会给我一个智能指针,其中包含指向uint8_t数组的指针,因此operator []应该索引到该数组中。我最好的猜测是发生了什么,而我说我想要一个指向uint8_t数组的指针的unique_ptr。我想我从中看到了几种方法,但我不确定哪种方法最好

  1. typedef std::unique_ptr<uint8_t[]> sha256hash; 编译,但我不完全确定我的重载运算符不会尝试将任何 unique_ptr打印到一个整数数组。
  2. 我为int数组创建一个容器结构,并在其周围放置一个unique_ptr。

1 个答案:

答案 0 :(得分:1)

由于@ PeterT的input我最终选择了第二个选项。自定义删除器似乎太过分了,这很容易集成到我现有的代码中。以下是我的更改:

//! Light wrapper around SHA256 digest
class SHA256Hash {
  //! The actual digest bits.
  uint8_t buff[SHA256::DIGEST_SIZE];
public:
  //! Pointer to a hash.
  typedef std::unique_ptr<SHA256Hash> ptr;

  //! Default constructor
  SHA256Hash() : buff() { }

  //! Operator to offer convenient buffer access
  uint8_t &operator[](const uint8_t i) { return buff[i]; }

  //! Operator to offer convenient buffer access
  const uint8_t &operator[](const uint8_t i) const { return buff[i]; }

  //! Offers access to the underlying digest
  uint8_t *get() { return (uint8_t *) &buff; }
};

// Delegate to the version that prints references
std::ostream &operator<<(std::ostream &os, const SHA256Hash::ptr &hashp) {
  os << *hashp;
  return os;
}

std::ostream &operator<<(std::ostream &os, const SHA256Hash &hash) {
    // Save old formatting
    std::ios oldFormat(nullptr);
    oldFormat.copyfmt(os);

    // Set up formatting
    os << std::setfill('0') << std::setw(2) << std::hex;

    // Do our printing
    for (int i = 0;i < SHA256::DIGEST_SIZE; i++)
      os << (int) hash[i];

    // Restore formatting
    os.copyfmt(oldFormat);

    return os;
}