Search code examples
c++stringc++11string-view

Use an external buffer for a string without copying


Assume that I have a function that gets const string& as its input for example:

void foo(const string& s);

And then I have an internal buffer const char* buffer; which I know the size of it.

I think if I create string inline, still one copy would happen:

foo(string(buffer, n));

But there is no need to copy the buffer because all things are constant and I just need the functionality of string class not the buffer that it creates.

I must mention that I am not sure that copy happens or not, But looking at the constructor of string all of them said that copy would happen. I don't know compiler optimization can understand such situations or not and I could not find a way to sure that copy happened or not.

Is there any way to use an external buffer for string, or at least a way to sure that copy happens or not. I am using std string and c++11 currently.


Solution

  • Yes, copying is always happening. BTW, you don't need to wrap std::string(buffer) as the constructor std::string(char const*) is implicit and a simple

    foo(buffer);
    

    will implicitly copy the buffer into the string. If you are the author of foo you can add an overload

    void foo(char const*)
    

    that avoids the copying. However, C strings are suffering from the problem that the null terminator is part of the string APIs, and so you can't easily create substrings without mutating the underlying string (a la strtok).

    The Library Fundamentals Technical Specification contains a string_view class that will eliminate the copying like char const*, but preserves the subset capability of std::string

    #include <iostream>
    #include <experimental/string_view>
    
    void foo(std::experimental::string_view v) { std::cout << v.substr(2,8) << '\n'; }
    
    int main()
    {
        char const* buffer = "war and peace";
        foo(buffer);
    }
    

    Live Example (requires libstdc++ 4.9 or higher in C++14 mode).