来自StringPiece class in Chromium's source code的文档:
// A string-like object that points to a sized piece of memory.
//
// Functions or methods may use const StringPiece& parameters to accept either
// a "const char*" or a "string" value that will be implicitly converted to
// a StringPiece.
//
// Systematic usage of StringPiece is encouraged as it will reduce unnecessary
// conversions from "const char*" to "string" and back again.
使用示例:
void foo(StringPiece const & str) // Pass by ref. is probably not needed
{
// str has same interface of const std::string
}
int main()
{
string bar("bar");
foo(bar); // OK, no mem. alloc.
// No mem. alloc. either, would be if arg. of "foo" was std::string
foo("baz");
}
这似乎是一个非常重要且显而易见的优化,我无法理解为什么它不会更普遍,以及为什么类似于StringPiece的类不在标准中。
为什么我不应该在自己的代码中使用此类替换string
和char*
参数的使用? C ++标准库中是否有类似的内容?
更新即可。我已经了解到LLVM的源代码使用了类似的概念:StringRef类。
答案 0 :(得分:8)
稍后,但是......
StringPiece背后的想法非常好。该类可以捕获std::string
和const char *
并将它们传递给函数。这是一个例子:
void process(const StringRef s){
// do something
}
process("Hello"); // const char *
std::string s = "Hello";
process(s); // std::string
process(std::string("Hello")); // std::string rvalue
如果函数接受std::string
,如果传递const char *
并且复制了整个字符(例如使用memcpy
),则实际创建临时对象。
您也不需要担心实时,因为您正在将StringRef
传递给函数/方法。
有这样的课程:
Google - StringPiece
boost - boost :: string_ref
LLVM - StringRef
我自己(不完整)的实施可以在这里看到:
https://github.com/nmmmnu/HM3/blob/master/include/stringref.h
2016年更新:
在C ++ 17中,有std::string_view
。我没有详细研究它,但总的来说它有相同的想法。与我的实现类似,它有constexpr
c-tor,因此您可以在编译时创建对象并将其与其他constexpr
函数一起使用。
答案 1 :(得分:4)
这个问题已经得到了很好的回答,但为了提供更多背景信息,StringPiece
模式在Google内部广泛使用并且已经存在多年。强烈建议使用Google编码指南,这几乎肯定是Chrome(以及随后的Chromium)采用它的原因。
答案 2 :(得分:2)
StringPiece
保存指向传递给其构造函数的字符串数据的指针。因此,它依赖于该字符串的生命周期比StringPiece更长。如果您使用StringPiece作为函数参数,则可以保证这一点。如果您在类成员中保留字符串的副本,则不是这样。
它不像std :: string那么通用,它绝对不是它的替代品。
答案 3 :(得分:0)
标准试图完全偏离const char *而不是字符串,因此添加更多转换选项是没用的。
另请注意,一个好的形成的程序应该使用字符串或const char * all around;)。
答案 4 :(得分:0)
StringPiece很棒但是这些碎片没有被终止。如果需要传递给采用空终止字符串的低级接口,则需要将字符串复制到以空字符结尾的字符串中。
(并非所有人都购买了STL或std :: string。)
答案 5 :(得分:-7)
因为为什么要打扰?通过复制省略和/或通过引用传递,通常也可以避免std::string
的内存分配。
C ++中的字符串情况很容易混淆,没有添加更多的字符串类。
如果要从头开始重新设计语言,或者向后兼容性不是问题,那么这是可以对C ++中的字符串处理进行的许多可能的改进之一。但是现在我们遇到了char*
和std::string
两个问题,在混合中添加一个stringref样式的类会引起很多混乱,但收益有限。
除此之外,使用一对迭代器获得更多的效果是不是同样的效果?
如果我想传递一系列字符,无论它们是属于字符串还是char*
,为什么我不应该只使用一对迭代器来分隔它们?