简体   繁体   English

C++ 使用在编译时确定的字符串文字长度值

[英]C++ use string literal length value determined at compile time

Is the following a reasonable approach?以下是合理的方法吗? Is there even a simpler way to avoid strlen() calls at runtime while keeping global constants defined as const char* const?是否有更简单的方法可以避免在运行时调用 strlen(),同时保持全局常量定义为 const char* const? I'm on C++17.我在 C++17 上。

constexpr auto PREFIX = "myprefix";

std::string addPrefix(const std::string& s)
{
    static constexpr std::string_view prefix(PREFIX);
    std::string buf;
    buf.reserve(s.size() + prefix.size());
    buf += prefix;
    buf += s;
    return buf;
}

Yes, your code is performant.是的,您的代码是高性能的。 You can paste it into Compiler Explorer, with optimization flags, to see the result.您可以将其粘贴到带有优化标志的编译器资源管理器中,以查看结果。 The string_view will be done at compile time, and the length will be known at compile time so it doesn't do the counting off of strlen . string_view将在编译时完成,长度将在编译时已知,因此它不会计算strlen

Is there a simpler way?有没有更简单的方法? Yes, but essentially the same thing just packaged to be reusable.是的,但本质上是相同的东西,只是打包成可重复使用的。 I have (as do big libraries such as absil) an append function that takes any number of arguments, and does just that: adds up the lengths first, reserves, then copies.我有(和 absil 等大型图书馆一样)一个append function,它采用任意数量的 arguments,并且这样做:首先将长度相加,然后保留,然后复制。

A constexpr string_view is a very understandable way to get the length at compile-time, and it is generally good at replacing raw character literals because you get all the string class members on it etc, and you don't get distracted by the allocation for the trailing \0 . constexpr string_view是在编译时获取长度的一种非常容易理解的方法,它通常擅长替换原始字符文字,因为您可以获得所有string class 成员等,并且您不会因分配尾随\0 A more "minimal" way won't be any faster (after all, it's being done at compile time) and you have a separation between the string pointer and the length rather than encapsulating them, and you use an odd rare technique instead of this general one.一个更“最小”的方式不会更快(毕竟,它是在编译时完成的)并且你在字符串指针和长度之间有一个分离而不是封装它们,你使用一种奇怪的罕见技术而不是这个一般的一个。 So, just use this.所以,就用这个吧。 It's good.很好。

update更新

As Jarod42 points out, PREFIX as you defined it has type const char* .正如 Jarod42 指出的那样,您定义的PREFIX具有类型const char* To clarify, the lexical string literal "myprefix" has type const char[9] .澄清一下,词法字符串文字"myprefix"的类型为const char[9] But the way you used auto it decays to a pointer.但是您使用auto的方式会衰减为指针。 Even so, the constexpr constructor for string_view takes a const char* and scans for the terminating \0 , so having the length of the array does not help (you could have a nul in the middle of the array).即便如此, string_view 的constexpr string_view采用const char*并扫描终止\0 ,因此拥有数组的长度并没有帮助(您可以在数组中间有一个 nul )。

You should declare constant lexical string literals like this:您应该像这样声明常量词法字符串文字:

constexpr char s1[] = "the letters";

because it directly names the array of characters.因为它直接命名字符数组。 If you write:如果你写:

constexpr const char* s2 = "more letters";

you end up with another chunk of memory to represent the pointer, which is what gets named s2 , in addition to the actual array of characters.除了实际的字符数组之外,您最终会得到另一块 memory 来表示指针,该指针被命名为s2

Your use of auto is the same as s2 .您对auto的使用与s2相同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM