有没有什么理由说StringPiece / StringRef成语不是更受欢迎?

时间:2010-01-31 18:13:28

标签: c++ string

来自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的类不在标准中。

为什么我不应该在自己的代码中使用此类替换stringchar*参数的使用? C ++标准库中是否有类似的内容?

更新即可。我已经了解到LLVM的源代码使用了类似的概念:StringRef类。

6 个答案:

答案 0 :(得分:8)

稍后,但是......

StringPiece背后的想法非常好。该类可以捕获std::stringconst 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*,为什么我不应该只使用一对迭代器来分隔它们?