【发布时间】:2013-11-20 21:28:57
【问题描述】:
我有一个操作字符串的函数,我需要它同时处理 C 样式字符串和 C++ std::string:
// C-style overload
void TransformString(const char *in_c_string, char *out_string);
// C++ std::strings overload
std::string TransformString(const std::string &in_string);
为了避免冗余代码,我可以只在其中一个中实现实际算法,然后让另一个调用它。因此,如果将实现放在 C++ 重载函数中,那么 C 风格的函数将如下所示:
void TransformString(const char *in_c_string, char * out_c_string) {
std::string in_string(in_c_string);
std::string out_string = TransformString(in_string); // call C++ std::string overload
strcpy(out_c_string, out_string.c_str()); // unwanted memory copy
}
我的问题是:我可以在没有额外副本(从std::string 内部缓冲区到 C 样式字符串)的情况下执行此操作(仅在一个函数中实现算法)吗?我的第一个想法是尝试“窃取”缓冲区,就像字符串移动构造函数一样,但是在搜索网络时,似乎没有安全的方法可以做到这一点,因为它是特定于实现的。如果我在 C 风格的函数中编写算法,问题与在 C++ 函数中的问题相同,我必须为 char* 字符串分配空间,然后将其移动到 std::string 对象。
必须提一下,在转换完成之前我不知道结果字符串的大小。
谢谢。
编辑
缓冲区的大小在这里不是问题(我知道最大大小并且函数接收分配的缓冲区)。 我不能只返回 std::string.c_str() ,因为当 std::string 对象被销毁时(就在返回发生之后),缓冲区将变得无效。 我已更改变量 out_c_string 的名称。 (感谢 0x499602D2)
【问题讨论】:
-
由于事先不知道输出大小,调用者无法为结果分配内存。然后我看不出你的 C 风格的重载是如何工作的。您需要
char **out_string作为第二个参数(或者只返回char *) -
您的示例中有两个名为
out_string的变量。 -
你能不能只写
std::string的代码,然后从c风格的字符串函数中调用那个方法并在返回值上使用std::string.c_str()? -
我不知道实际大小,但我知道最大大小并且函数接收分配的缓冲区。
-
我不能只返回 std::string.c_str() 因为当 std::string 对象被销毁时缓冲区会失效
标签: c++ c string buffer move-semantics