c++ - 如何在不复制和保留 std::string 对象的情况下获得 C++ std::string char 数据的所有权?

标签 c++ string c++11 buffer iostream

如何在不复制和不保留源 std::string 对象的情况下取得 std::string char 数据的所有权? (我想在不同类型之间使用移动语义。)

我使用 C++11 Clang编译器和 Boost .

基本上我想做一些等同于此的事情:

{
    std::string s(“Possibly very long user string”);
    const char* mine = s.c_str();

    // 'mine' will be passed along,
    pass(mine);

    //Made-up call
    s.release_data();

    // 's' should not release data, but it should properly destroy itself otherwise.
}

澄清一下,我确实需要在以后摆脱 std::string:。该代码处理字符串和二进制数据,并且应该以相同的格式处理它们。我确实想要来自 std::string 的数据,因为它来自另一个与 std::string 一起工作的代码层。

为了在我遇到想要这样做的地方给出更多的观点:例如,我有一个异步套接字包装器,它应该能够从用户那里获取 std::string 和二进制数据以进行写入。两个“API”写入版本(采用 std::string 或行二进制数据)在内部解析为相同(二进制)写入。我需要避免任何复制,因为字符串可能很长。

WriteId     write( std::unique_ptr< std::string > strToWrite )
{

    // Convert std::string data to contiguous byte storage
    // that will be further passed along to other
    // functions (also with the moving semantics).
    // strToWrite.c_str() would be a solution to my problem
    // if I could tell strToWrite to simply give up its
    // ownership. Is there a way?

    unique_ptr<std::vector<char> > dataToWrite= ??

    //
    scheduleWrite( dataToWrite );
}

void scheduledWrite( std::unique_ptr< std::vecor<char> > data)
{
    …
}

本例中的 std::unique_ptr 用于说明所有权转移:任何其他具有相同语义的方法对我来说都很好。

我想知道这种特定情况(使用 std::string char 缓冲区)的解决方案以及字符串、流和类似一般问题的此类问题:tips to approach moving buffers around between string, stream, std containers and buffer types .

当涉及到在不同 API/类型之间传递缓冲区数据而不复制时,我还希望获得有关 C++ 设计方法和特定技术的提示和链接。我提到但没有使用流,因为我对这个问题犹豫不决。

最佳答案

How can I take ownership of std::string char data without copying and withoug keeping source std::string object ? (I want to use moving semantics but between different types)

您无法安全地执行此操作。

对于特定的实现,在某些情况下,您可以做一些糟糕的事情,比如使用别名来修改字符串内的私有(private)成员变量,以欺骗字符串认为它不再拥有缓冲区。但是,即使您愿意尝试这样做,也不一定总是有效。例如。考虑小字符串优化,其中字符串没有指向保存数据的某个外部缓冲区的指针,数据在字符串对象本身内部。


如果您想避免复制,可以考虑将接口(interface)更改为 scheduledWrite。一种可能性是这样的:

template<typename Container>
void scheduledWrite(Container data)
{
    // requires data[i], data.size(), and &data[n] == &data[0] + n for n [0,size)
    …
}

// move resources from object owned by a unique_ptr
WriteId write( std::unique_ptr< std::vector<char> > vecToWrite)
{
    scheduleWrite(std::move(*vecToWrite));
}

WriteId write( std::unique_ptr< std::string > strToWrite)
{
    scheduleWrite(std::move(*strToWrite));
}

// move resources from object passed by value (callers also have to take care to avoid copies)
WriteId write(std::string strToWrite)
{
    scheduleWrite(std::move(strToWrite));
}

// assume ownership of raw pointer
// requires data to have been allocated with new char[]
WriteId write(char const *data,size_t size) // you could also accept an allocator or deallocation function and make ptr_adapter deal with it
{
    struct ptr_adapter {
        std::unique_ptr<char const []> ptr;
        size_t m_size;
        char const &operator[] (size_t i) { return ptr[i]; }
        size_t size() { return m_size; }
    };

    scheduleWrite(ptr_adapter{data,size});
}

关于c++ - 如何在不复制和保留 std::string 对象的情况下获得 C++ std::string char 数据的所有权?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11301446/

相关文章:

c# - 在应用程序中嵌入 OneNote

java - 为什么java的 String split ("\\s") 数组中有一个空字符串?

javascript - 如何用 `replace`方法将多个关键字替换成相应的关键字?

c++ - is_convertible 用于多个参数

c++ - TrueType 字体缩放会导致文本模糊?

c++ - 如何将参数传递给包装在 std::function<void()> 中的成员函数?

c++ - 什么是空终止字符串?

c++ - 在 find_if 中使用谓词

c++ - `class template Example<int>;` 语句对 C++11 意味着什么?

c++ - 我怎样才能等待多件事