微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

StringPiece是否与字符串右值引用冲突?

如何解决StringPiece是否与字符串右值引用冲突?

我已经在一些开源项目中看到了StringPiece类,比如说mudu网络库和pcre。实现StringPiece的类如下:

// You can use StringPiece as a function or method parameter. A StringPiece
// parameter can receive a double-quoted std::string literal argument,a “const
// char*” argument,a std::string argument,or a StringPiece argument with no
// data copying. Systematic use of StringPiece for arguments reduces data
// copies and strlen() calls.
class StringPiece {
 public:
  StringPiece() : ptr_(nullptr),length_(0) {}
  StringPiece(const char* str) : ptr_(str),length_(strlen(str)) {}
  StringPiece(const unsigned char* str)
      : ptr_(reinterpret_cast<const char*>(str)),length_(strlen(ptr_)) {}
  StringPiece(const std::string& str)
      : ptr_(str.c_str()),length_(str.size()) {}
  StringPiece(const char* offset,int len) : ptr_(offset),length_(len) {}
  const char* data() const { return ptr_; }
  size_t size() const { return length_; }
  bool empty() const { return length_ == 0; }
  const char* begin() const { return ptr_; }
  const char* end() const { return ptr_ + length_; }

  void clear() {
    ptr_ = nullptr;
    length_ = 0;
  }
  void set(const char* buf,size_t len) {
    ptr_ = buf;
    length_ = len;
  }
  void set(const char* buf) {
    ptr_ = buf;
    length_ = strlen(ptr_);
  }
  void set(const void* buf) {
    ptr_ = static_cast<const char*>(buf);
    length_ = strlen(ptr_);
  }
  void remove_prefix(size_t n) {
    assert(n < length_);
    ptr_ += n;
    length_ -= n;
  }
  void remove_suffix(size_t n) {
    assert(n < length_);
    length_ -= n;
  }
  char operator[](size_t i) const { return ptr_[i]; }

  bool operator==(const StringPiece& str) const {
    return ((str.length_ == length_) && (memcmp(ptr_,str.ptr_,length_) == 0));
  }

  bool operator!=(const StringPiece& str) const { return !(*this == str); }

  std::string as_string() const { return std::string(ptr_,length_); }

  bool start_with(const StringPiece& str) const {
    return (length_ >= str.length_) &&
           (0 == memcmp(ptr_,str.length_));
  }

#define STRINGPIECE_BINARY_PREDICATE(cmp,auxcmp)                              \
  bool operator cmp(const StringPiece& str) const {                            \
    int r =                                                                    \
        memcmp(ptr_,length_ < str.length_ ? length_ : str.length_); \
    return ((r auxcmp 0)) || ((0 == r) && (length_ cmp str.length_));          \
  }
  STRINGPIECE_BINARY_PREDICATE(<,<)
  STRINGPIECE_BINARY_PREDICATE(<=,<)
  STRINGPIECE_BINARY_PREDICATE(>,>)
  STRINGPIECE_BINARY_PREDICATE(>=,>)
#undef STRINGPIECE_BINARY_PREDICATE
  int compare(const StringPiece& str) {
    int r =
        memcmp(ptr_,length_ < str.length_ ? length_ : str.length_);
    if (0 == r) {
      if (length_ < str.length_)
        r = -1;
      else if (length_ > str.length_)
        r = 1;
    }
    return r;
  }

 private:
  const char* ptr_;
  size_t length_;
};

如上所述,StringPiece设计为1)节省一些不必要的数据复制; 2)在对象中接收两个不同的类型参数。 我编写了一些代码来学习如何使用StringPiece,但出现了一些错误。我的代码如下:

#include "StringPiece.h"
#include <iostream>
using namespace std;

void foo1(string&& str){
    cout << str << endl;
}

void foo1(const StringPiece& str){
    cout << str.as_string() << endl;
}

int main(void){
    foo1("1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
    return 0;
}

我得到的错误如下:

enter image description here

在我看来,StringPiece有点像boost :: string_ref。它可以让您瞥见它不拥有的字符串。因此,我认为有必要提供foo1的重载版本,该版本可以接收rvalue字符串参数。有什么要解决这个问题的吗?我的意思是,仅当我使用未命名的字符串对象作为参数时,foo1(string&&)才会被调用。在其他情况下,包括使用const char *作为参数,将调用foo1(const StringPiece&)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。