c++ - std::string 实现是否符合 's.c_str() + s.size()' 不一定与 '&s[s.size()]' 相同?

标签 c++ string c++11 language-lawyer

§21.4.5 [string.access]

const_reference operator[](size_type pos) const;
reference operator[](size_type pos);

Returns: *(begin() + pos) if pos < size(). Otherwise, returns a reference to an object of type charT with value charT(), where modifying the object leads to undefined behavior.

至少对我来说,第二部分意味着这个“charT 类型的对象”可能位于存储在 std::string 中的序列之外。目的。符合 operator[] 的示例实现:

reference operator[](size_type pos){
  static contexpr charT default = charT();
  if(pos == size())
    return default;
  return buf[pos];
}

现在,c_str()/data() , 是根据 operator[] 指定的:

§21.4.7 [string.accessors]

const charT* c_str() const noexcept;
const charT* data() const noexcept;

Returns: A pointer p such that p + i == &operator[](i) for each i in [0,size()].

这将使上面的 operator[]实现不一致,如p + size() != &operator[](size()) .但是,通过一些技巧,您可以避免这个问题:

reference operator[](size_type pos){
  static contexpr charT default = charT();
  if(pos == size() && !evil_context) // assume 'volatile bool evil_context;'
    return default;
  return buf[pos];
}

struct evil_context_guard{
  volatile bool& ctx;
  evil_context_guard(volatile bool& b)
    : ctx(b) {}
  ~evil_context_guard(){ b = false; }
};

const charT* c_str() const noexcept{
  evil_context_guard g(evil_context = true);
  // now, during the call to 'c_str()', the requirement above holds
  // 'p + i == &operator[](i) for each i in [0,size()]'
  const charT* p = &buf[0];
  assert(p+size() == &operator[](size()));
  return p;
}

现在,显而易见的问题是......

上面的代码真的是合规的还是我忽略了什么?

最佳答案

忽略给定的代码,只考虑问题,我认为

  • 不幸的是,答案似乎是"is",并且
  • 这肯定不是标准的意图

因此,它似乎是一个缺陷

检查 list of known library defects显然这个问题还没有被报道。

因此,正如我在聊天中所说,我建议将它发布到 [comp.std.c++],以便解决它是否真的是一个缺陷的问题,如果是,将其放入缺陷列表并修复。

关于c++ - std::string 实现是否符合 's.c_str() + s.size()' 不一定与 '&s[s.size()]' 相同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11809849/

相关文章:

c++ - 为 GCC 4.5.3 模拟 nullptr & nullptr_t

c++ - Thrust 复杂内积在 GPU 上的运行速度比在 CPU 上的 STL 实现慢

c++ - 捕获从其参数抛出的函数中的异常

string - 在 gdb 中,如何将字符串写入内存?

c++ - 跨平台线程亲和函数

c++ - Boost d_ary_heap/priority_queue 编译错误: deleted function

C++ 关系运算符生成器

c++ - 当更多信息打印到屏幕上时,使 boost::progress_display 工作

C++如何在字符串中使用变量

c++ - libssh2 - 使用 SFTP 读取文件