【发布时间】:2022-01-05 19:39:19
【问题描述】:
std::transform,从 C++20 开始,声明为 constexpr. 我有一堆字符串实用函数,它们接受 std::string 参数,但很多用法最终只是传递了小而短的字符编译时的文字序列。我想我会利用这一事实并声明 constexpr 的版本并采用 std::string_views 而不是创建临时的 std::string 变量只是为了把它们扔掉......
原始STD::STRING 版本:
[[nodiscard]] std::string ToUpperCase(std::string string) noexcept {
std::transform(string.begin(), string.end(), string.begin(), [](unsigned char c) -> unsigned char { return std::toupper(c, std::locale("")); });
return string;
}
新STD::STRING_VIEW 版本:
[[nodiscard]] constexpr std::string_view ToUpperCase(std::string_view stringview) noexcept {
std::transform(stringview.begin(), stringview.end(), stringview.begin(), [](unsigned char c) -> unsigned char { return std::toupper(c, std::locale("")); });
return stringview;
}
但 MSVC 抱怨:
error C3892: '_UDest': you cannot assign to a variable that is const
有没有办法用std::string_view 调用std::transform 并将其放回std::string_view 或者我将不得不创建一个本地字符串并返回它,从而违背了使用std::string_view 的目的首先?
[[nodiscard]] constexpr std::string ToUpperCase(std::string_view stringview) noexcept {
std::string copy{stringview};
std::transform(stringview.begin(), stringview.end(), copy.begin(), [](unsigned char c) -> unsigned char { return std::toupper(c, std::locale("")); });
return copy;
}
【问题讨论】:
-
string_view是字符序列的不可变视图。它看起来但没有触摸。这就是它不需要复制任何内容来形成const char[]C 样式字符串文字的视图的全部原因。 -
没有办法避免复制,因为
string_view只提供 const 访问 - 这很好。您希望如何避免在auto upper = ToUpperCase("foo");中复制? -
std::string_view指的是一个恒定的连续序列。为什么不试试std::span<char>? -
@ecatmur - 因为它会有不同的语义:就地修改。
-
@Eugene 这听起来像是他想要的。他在最后特别问是否有办法修改它。
标签: c++ c++20 string-view toupper tolower