cpt*_*ssa 11 c++ string-view c++17
我正在编写许多 string_view 擅长的解析器代码,并且已经开始喜欢这种类型。我最近读了 ArthurO'Dwyer 的文章std::string_view is aborrow type,他的结论是 string_view (和其他“借用类型”)可以使用,只要它们“...仅作为函数参数和 for 循环出现”控制变量。” (有几个例外)。
但是,我最近开始使用 string_view 作为将枚举转换为字符串(我经常使用)的函数的返回值,例如这个Compiler Explorer:
#include <iostream>
#include <string>
#include <array>
#include <algorithm>
enum class Color
{
red, green, blue, yellow,
last // Must be kept last
};
constexpr std::string_view toString(Color color);
// The rest would normally be in a .cpp file
using cts = std::pair<Color, std::string_view>;
constexpr std::array colorNames = {cts{Color::red, "red color"},
cts{Color::green, "green color"},
cts{Color::blue, "blue color"},
cts{Color::yellow, "yellow color"}};
static_assert(colorNames.size() == static_cast<size_t>(Color::last));
constexpr std::string_view toString(Color color)
{
// Normally calling a library function (which also checks for no match), instead of this:
return std::ranges::find(colorNames, color, &cts::first)->second;
}
int main()
{
auto s1 = toString(Color::green);
auto s2 = toString(Color::blue);
std::cout << s1 << ' ' << s2 << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
我这样做的原因是:
所以我的问题是,以这种方式返回 string_view 是否不安全(或 UB),或者我可以继续凭良心这样做吗?
或者,是否有更好(更快/更安全)的方法来解决枚举到字符串的一般问题?
添加:在阅读了G. Sliepen的非常好的答案后,我想在他的答案中添加我的评论:我也经常有相反的功能,例如:
constexpr Color fromString(string_view str)
{
// No-match handling omitted
return std::ranges::find(colorNames, color, &cts::second)->first;
}
Run Code Online (Sandbox Code Playgroud)
在这些情况下,我确实需要将翻译作为单独的表,以便两个函数都可以使用它。但在许多其他情况下,包含 switch 语句的函数是最简单、最好的。
G. *_*pen 12
以这种方式返回 string_view 是不安全的(或 UB),还是我可以继续凭良心这样做?
是的。你的使用方式完全没问题。函数string_view
返回的toString
数据形成一个数据视图,该视图将保持完整,直到程序终止。
或者,是否有更好(更快/更安全)的方法来解决枚举到字符串的一般问题?
您可以创建一个内部constexpr
带有 - 语句的函数,如下所示:switch
constexpr std::string_view toString(Color color)
{
switch (color) {
case Color::red: return "red";
case Color::green: return "green";
...
}
}
Run Code Online (Sandbox Code Playgroud)
如果函数在编译时求值,效率应该没有差异。但是编译器可以检查您是否case
为所有可能的Color
s 添加了 -statement,如果没有,它会发出警告。也没有必要采用Color::last
这种方式。
保持 theenum
和std::array
orswitch
语句同步可能很烦人,特别是如果您有很多枚举值。X 宏在这里可能会有所帮助。
归档时间: |
|
查看次数: |
5828 次 |
最近记录: |