c++11 - 对于非空字符串,data() 是否保证等于 &front()?

标签 c++11

我经常使用 std::string 作为通用二进制缓冲区。这会导致获取可变数据指针时出现问题,因为当字符串 s 为空时,您无法使用 &s.front()

这就是为什么我有这个辅助函数(它首先执行 string::data 应该执行的操作):

char* data(string& s)
{
    if (!s.empty())
        return &s.front();
    else
        return const_cast<char*>(s.data());
}

这符合标准,因为字符串是连续存储的,并且不允许覆盖终止 0 字符。

我喜欢它,因为尺寸检查似乎得到了优化。

但我更想要这个功能:

char* data(string& s)
{
    return const_cast<char*>(s.data());
}

我只是不确定这样做是否真的合法。

毫无疑问它会起作用,如果大小检查没有得到优化,我会使用这个版本。

最佳答案

我认为有一个怪癖尚未被注意到。这似乎是一个极端的边缘情况,我只是通过仔细阅读才发现的。 string::data 保证它返回的缓冲区包含字符串和一个空终止符。 std::string 但是不保证其缓冲区有空终止符。

因此,我相信技术上符合要求的实现无法在创建字符串或调用 string::front 时添加空终止符,并且仅在调用 string::data 时添加它string::c_str 已制作。

因此,即使你得到的指针是相同的,我也不确定副作用是否保证是相同的,使得它们不一定是等价的。 (在有人问这如何在 const 字符串上工作之前,我不明白为什么确认实现无法声明内部缓冲区 mutable 并修改 null,即使对于 >const 函数假设它执行适当的锁定以确保同时访问安全。)

然而,实际执行此操作的实现看起来要么设计得很糟糕,要么非常残酷。

关于c++11 - 对于非空字符串,data() 是否保证等于 &front()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20588339/

相关文章:

成员的 C++11 decltype

multithreading - 动态分配的实现类 std::async-ing 其成员

c++ - 做什么 ({});在 C++ 中是什么意思?

c++ - 关于 C++ 非 POD union 的问题

C++11 外部作用域变量声明为 auto

c++ - 为什么不能将平凡的派生类视为聚合类型?

c++ - 我想杀死一个 std::thread 使用它的线程对象?

c++ - std::initializer_list 的语义

c++ - 在 C++11 中实现线程安全方法的正确方法

C++11 通过推导类型参数传递成员函数调用?