8

在浏览 C++14/C++1y (n3690) 的草稿时,我注意到在第 21.7 节中引入了basic_string文字后缀

inline namespace literals {
inline namespace string_literals {
  // 21.7, suffix for basic_string literals:
  string operator "" s(const char *str, size_t len);
  u16string operator "" s(const char16_t *str, size_t len);
  u32string operator "" s(const char32_t *str, size_t len);
  wstring operator "" s(const wchar_t *str, size_t len);
}
}

我的问题是:

  • basic_string文字是否有可能在运行时更快?
  • 我的“天真”实施完全错误吗?
  • ROM 中的数据布局可以与basic_string文字不同,或者在编译时与运行时有任何其他差异吗?

背景

我知道这允许直接使用这样的字符串文字:

std::string s1 = "A fabulous string"s;

void sfunc(std::string arg);

int main() {
    sfunc("argument"s);
}

但是,与依赖转换构造函数 string(const char*)相比,这有什么优势呢?

“旧”代码如下所示:

std::string s1 = "A fabulous string";  // c'tor string(const char*)

void sfunc(std::string arg);

int main() {
    sfunc("argument");   // auto-conversion via same c'tor
}

据我所见,实现operator "" s()基本上是这样的:

std::string operator "" s(const char* lit, size_t sz) {
    return std::string(lit, sz);
}

因此,只需使用相同的 c'tor。我的猜测是,这必须在运行时完成,我错了吗?

编辑:正如Nicol Bolas在下面正确指出的那样,我的示例没有使用相同的构造函数,而是使用具有额外长度的构造函数——显然,这对构造非常有用。这给我留下了一个问题:编译器将字符串文字放入 ROM 或在编译时类似的东西是否更好?

4

3 回答 3

6
  • 使用 basic_string 文字是否有可能在运行时更快?

如前所述,字符串长度是已知的并自动传递给构造函数。

  • 我的“天真”实施完全错误吗?

不,这是正确的。

  • ROM 中的数据布局能否与 basic_string 文字不同,或者在编译时与运行时有任何其他差异?

可能不会,因为相关的basic_string构造函数不constexpr适合静态初始化,所以可能不能放入ROM中,必须在运行时完成。

于 2013-08-27T11:53:52.490 回答
5

因此,只需使用相同的 c'tor。

好的,让我们看看它的外观:

string fromLit = "A fabulous string"s;
string fromBare = string("A fabulous string");

看到有什么遗漏了fromBare吗?让我为你拼写:

string fromBare = string("A fabulous string"/*, NOTHING*/);

是的,如果没有......得到它的长度,你就无法得到字符串的长度。这意味着fromBare必须遍历文字才能找到\0字符。在运行时。fromLit将不会; 编译器提供字符串的长度作为编译时确定的参数。任何值得使用的编译器只会将长度烘焙到可执行代码中。

即使不是这样,由于其他原因,它仍然更好。考虑一下:

void SomeFunc(const std::string &);
void SomeFunc(const char *);

SomeFunc("Literal");
SomeFunc("Literal"s);
SomeFunc(std::string("Literal"));

最后两个做同样的事情(减去我之前提出的观点),但其中一个短得多。即使你雇用using std::string(或愚蠢地using namespace std;),第二个仍然更短。然而很清楚到底发生了什么。

于 2013-08-26T08:35:49.597 回答
1

它提供了更多的编译时安全性。

考虑如何构造一个带有嵌入 null 的 std::string?

从包含空字符的字符串文字构造 a 的唯一方法std::string是指定字符串文字的大小(容易出错),使用initializer_list语法(冗长)或通过多次调用来执行某种循环push_back(甚至更冗长)。但是,使用文字构造函数时,会自动为您传递大小,从而消除可能的错误来源。

于 2013-10-04T00:27:21.430 回答