簡體   English   中英

C ++如何選擇要使用的運算符重載?

[英]How does C++ choose which operator overload to use?

我正在編寫一組用於自定義序列化和反序列化的類。 我認為我會使用<<和>>運算符,因為它們通常傳達這種含義。 讓我們從一個用於處理寫入通用流的類開始。

class Writer
{
public:
  virtual void writeBytes(const void* p, size_t n) = 0;
  template <typename T> void write(const T& v)
  {
    writeBytes(&v, sizeof(v));
  }
  template <typename T> Writer& operator<<(const T& v)
  {
    write(v);
    return *this;
  }
};

然后是一個可序列化的接口,即提供了自己的序列化方法。

class Serializable
{
public:
  virtual Writer& serialize(Writer& writer) const = 0;
};

Writer& operator<<(Writer& writer, const Serializable& s)
{
  s.serialize(writer);
  return writer;
}

最后,我寫了一個如何使用它的示例:可序列化的緩沖區。

class SerializableBuffer : public Serializable
{
public:
  SerializableBuffer() : data_(NULL), length_(0) { }
  SerializableBuffer(void* data, size_t length) : data_(data), length_(length) { }
  virtual Writer& serialize(Writer& writer) const
  {
    writer.writeBytes(data_, length_);
    return writer;
  }
private:
  void* data_;
  size_t length_;
};

所以這是有趣的部分。 顯然,如果我使用方法調用,它將完全按照預期進行。 但是使用<<操作符顯示出一些古怪之處。 我的第一個嘗試是執行以下操作:

  unsigned char input[] = { 0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0x12, 0x34 };
  SerializableBuffer sb(input, sizeof(input));

  unsigned char d[8]; 
  BufferWriter writer(buffer(d));

  writer << sb;

這將失敗,因為輸出緩沖區不夠大。 如果我添加一個printf,結果表明它正在Writer類中調用模板! 這是古怪的部分,以下作品。

  unsigned char input[] = { 0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0x12, 0x34 };
  SerializableBuffer sb(buffer(input));

  unsigned char d[8]; 
  BufferWriter writer(buffer(d));

  writer << (Serializable&)sb;

我猜模板引擎勝過后代嗎? 誰能解釋這是怎么回事,為什么?

它非常簡單-僅遵循重載解析規則。 您有兩個重載operator << ,當第一個參數是Writer &或子類時,它們可能會匹配:

template <typename T> Writer& Writer::operator<<(const T& v);
Writer& operator<<(Writer& writer, const Serializable& s);

當第二個參數是SerializableBuffer ,第一個參數可以完全匹配,而第二個參數可以與轉換匹配。 由於完全匹配會更好,因此首先匹配。

當第二個參數是Serializable ,兩者都完全匹配,因此第二個參數更好,因為它不是模板。

如果當參數是Serializable的子類時要使模板不匹配,則可以使用enable_if

template <typename T>
std::enable_if<!std::is_base_of<Serializable, T>::value, Writer &>::type
operator<<(const T &v)

這將導致該模板對於Serializable任何子類都無法實例Serializable

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM