在不复制的情况下为字符串使用外部缓冲区
Use an external buffer for a string without copying
假设我有一个函数将 const string&
作为其输入,例如:
void foo(const string& s);
然后我有一个内部缓冲区 const char* buffer;
,我知道它的大小。
我想如果我创建内联字符串,仍然会发生一个副本:
foo(string(buffer, n));
但是不需要复制缓冲区,因为所有的东西都是常量,我只需要字符串的功能 class 而不是它创建的缓冲区。
我必须提一下,我不确定复制是否会发生,但是看着 constructor of string 他们都说复制会发生。我不知道编译器优化是否可以理解这种情况,我找不到一种方法来确定是否发生了复制。
有没有什么方法可以为字符串使用外部缓冲区,或者至少有一种方法可以确保复制是否发生。我目前正在使用标准字符串和 c++11。
不,std::string
管理其缓冲区。你不能有一个使用外部缓冲区的字符串。在您执行 string(buffer, n)
的那一刻,这并不意味着您的字符串实例将拥有您的 buffer
并将其用作字符串,而是只会复制 buffer
的内容到其内部缓冲区。
是的,复制总是在发生。顺便说一句,你不需要包装 std::string(buffer)
因为构造函数 std::string(char const*)
是隐式的并且是一个简单的
foo(buffer);
会将缓冲区隐式复制到字符串中。如果您是 foo
的作者,您可以添加重载
void foo(char const*)
这样就避免了复制。但是,C 字符串存在空终止符是字符串 API 的一部分的问题,因此您不能在不改变底层字符串的情况下轻松创建子字符串(la strtok
)。
库基础技术规范包含一个 string_view
class,它将消除像 char const*
一样的复制,但保留了 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(在 C++14 模式下需要 libstdc++ 4.9 或更高版本)。
假设我有一个函数将 const string&
作为其输入,例如:
void foo(const string& s);
然后我有一个内部缓冲区 const char* buffer;
,我知道它的大小。
我想如果我创建内联字符串,仍然会发生一个副本:
foo(string(buffer, n));
但是不需要复制缓冲区,因为所有的东西都是常量,我只需要字符串的功能 class 而不是它创建的缓冲区。
我必须提一下,我不确定复制是否会发生,但是看着 constructor of string 他们都说复制会发生。我不知道编译器优化是否可以理解这种情况,我找不到一种方法来确定是否发生了复制。
有没有什么方法可以为字符串使用外部缓冲区,或者至少有一种方法可以确保复制是否发生。我目前正在使用标准字符串和 c++11。
不,std::string
管理其缓冲区。你不能有一个使用外部缓冲区的字符串。在您执行 string(buffer, n)
的那一刻,这并不意味着您的字符串实例将拥有您的 buffer
并将其用作字符串,而是只会复制 buffer
的内容到其内部缓冲区。
是的,复制总是在发生。顺便说一句,你不需要包装 std::string(buffer)
因为构造函数 std::string(char const*)
是隐式的并且是一个简单的
foo(buffer);
会将缓冲区隐式复制到字符串中。如果您是 foo
的作者,您可以添加重载
void foo(char const*)
这样就避免了复制。但是,C 字符串存在空终止符是字符串 API 的一部分的问题,因此您不能在不改变底层字符串的情况下轻松创建子字符串(la strtok
)。
库基础技术规范包含一个 string_view
class,它将消除像 char const*
一样的复制,但保留了 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(在 C++14 模式下需要 libstdc++ 4.9 或更高版本)。