我最近了解了 std::string_view 以及它如何比分配字符串快得多,因此我尝试在可能的情况下使用它来代替 std::string 。
有没有一种方法可以优化逐行解析文件的循环以使用 std::string_view 代替?
这是我正在处理的代码。
std::string line;
// loop until we find the cabbage tag
while (std::getline(csd, line))
{
//DO STUFF
if (line.find("</STOP>") != std::string::npos)
break;
}
Run Code Online (Sandbox Code Playgroud) 考虑这个片段:
#include <iostream>
#include <string>
#include <string_view>
using namespace std::literals;
class A
{
public:
std::string to_string() const noexcept
{
return "hey"; // "hey"s
}
std::string_view to_stringview() const noexcept
{
return "hello"; // "hello"sv
}
};
int main()
{
A a;
std::cout << "The class says: " << a.to_string() << '\n';
std::cout << "The class says: " << a.to_stringview() << '\n';
}
Run Code Online (Sandbox Code Playgroud)
我天真地期待一些警告,to_stringview()比如返回本地临时的引用,但 g++ 和 clang 都没有说什么,所以这段代码看起来合法并且有效。
由于这会产生预期的警告:
const std::string& to_string() const noexcept
{
return …Run Code Online (Sandbox Code Playgroud) std::transform从 C++20 开始,声明constexpr.我有一堆带std::string参数的字符串实用函数,但很多用法最终只是在编译时传递小而短的字符文字序列。constexpr我想我会利用这个事实并声明 和take s的版本,std::string_view而不是创建临时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;
}
Run Code Online (Sandbox Code Playgroud)
新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;
}
Run Code Online (Sandbox Code Playgroud)
但 MSVC 抱怨道:
error C3892: '_UDest': you cannot assign to a …Run Code Online (Sandbox Code Playgroud) 初始化std::stringstream 构造函数接受const string&以下参数:
explicit stringstream (const string& str,
ios_base::openmode which = ios_base::in | ios_base::out);
Run Code Online (Sandbox Code Playgroud)
这个接口在 C++98 中是合理的,但从 C++17 开始,我们有了std::string_view表示字符串的类的更便宜的替代方案。该类std::stringstream不会修改它接受的字符串,不拥有它,也不要求它以空终止。那么为什么不添加另一个接受 的构造函数重载呢std::string_view?是否存在任何障碍使该解决方案不可能(或不合理)屈服于Boost::Iostreams等替代方案?
我想知道如何正确处理函数中的字符串输入,如果我知道我将必须在其中创建一个副本以将其放入容器中。
我想这样做:
void foo(const string& s){
container.push(s);
}
Run Code Online (Sandbox Code Playgroud)
但是如果我传递一个 char* 字符串,我将制作 2 个副本,首先是在调用 foo 时,然后是在将其传递到容器时。
我的第二个想法是使用 string_view,正如人们常说的,如果你可以使用视图,你就应该使用。所以我的函数的第二个版本如下所示:
void foo2(string_view s){
container.push(string(s));
}
Run Code Online (Sandbox Code Playgroud)
好的,现在无论给我什么类型的字符串,我都会只制作一个副本。但后来我开始思考,为什么我不能接受一个字符串作为函数的参数,像这样简化它:
void foo3(string s){
container.push(std::move(s));
}
Run Code Online (Sandbox Code Playgroud)
但现在我必须确保我的容器正确利用移动语义,这样它最终不会制作另一个副本!由于此容器对象是模板化类型,因此意味着使用完美转发等,这本身就是大量工作。
目前我不知道该选择哪个选项,所以想请教您一些建议。我还觉得我想得太多了,因为这最终可能不会对性能产生太大影响,但我想做得正确。提前致谢。
因此,我正在阅读为较新版本的 CPP 编写的代码,并且经常看到几乎专门使用 string_view 文字,即使在简单的用例中也是如此。
例如:
std::cout<<"Hello world"sv<<std::endl;
Run Code Online (Sandbox Code Playgroud)
这有什么特别的原因吗?这显然与存储持续时间无关,因为 string_view 仅包装字符串文字。string_view 的开销是否较低?
谢谢您的宝贵时间。
我只知道C++17引入了std::string_view. 它不保存任何字符串,而是指向一个字符串。如果是这样,我对以下情况感到困惑:
std::string str = "abc";
std::string_view strV = str;
std::cout << strV << std::endl;
str = "1";
std::cout << strV << std::endl;
Run Code Online (Sandbox Code Playgroud)
我刚刚在网上的一些 c++17 编译器上尝试了这段代码,输出如下:
abc
1c
Run Code Online (Sandbox Code Playgroud)
显然,1c这不是我所期望的。
那么这是否意味着我们不应该更改分配给 a 的字符串std::string_view?
似乎C++ 17 string_view 的std :: hash函数不是constexpr.
在我看来,绑定到const char []的字符串视图可以在编译时进行散列(这将是非常甜蜜的),或者有什么可以防止这种情况?
istrstream非常适合我的需求 - 基本上,采用固定的char缓冲区,并给我一个简单的方法来提取行getline()和测试eof()
我正在将我们的项目转换为C++ 17合规性 - 这已被弃用istrsteam- 显然是因为有太多的C++程序员无法理解固定的缓冲内存管理(你认真吗?!)
无论如何,它istringstream提供了相同的使用语义,但它强制需要在构造时复制整个固定字符缓冲区.
这是一种反模式.
我正在寻找的是一种方法来string_view代替一个string用于istringstream替代,或者替代一个更好的替代,stringstream它本身处理外部管理的固定缓冲区(它只需指向它,它永远不需要担心管理该资源,只是一样strstream).
目前,在VS 2017中,这是非法的,如果我理解正确的话,在当前最先进的C++中是非法的(如果我错的话,我相信你会纠正我的!)
std::string_view raw_view(reinterpret_cast<const char *>(raw_buffer.get()), raw_buffer.size());
std::istringstream raw_stream(raw_view);
Run Code Online (Sandbox Code Playgroud)
那么 - 想法?
注意:Peter Sommerlad在这里为C++标准组织提出了这个确切的想法:http: //www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0448r1.pdf
是否可以在 constexpr 上下文中使用“if constexpr”来比较 std::string_view ?以及为什么 is_hello_2 和 is_hello_4 无法编译显示错误:“'s' 不是常量表达式”
static constexpr bool is_hello_1(auto s) {
return s == "hello";
}
static constexpr bool is_hello_2(auto s) {
if constexpr (s == "hello") {
return true;
}
return false;
}
static constexpr auto is_hello_3 = [](auto s) {
return s == "hello";
};
static constexpr auto is_hello_4 = [](auto s) {
if constexpr (s == "hello") {
return true;
}
return false;
};
Run Code Online (Sandbox Code Playgroud)
考虑到主要功能(https://godbolt.org/z/zEcnb8):
int main(int argc, char …Run Code Online (Sandbox Code Playgroud) c++ ×10
string-view ×10
c++17 ×6
c++20 ×3
std ×2
stdstring ×2
hash ×1
if-constexpr ×1
lifetime ×1
return ×1
string ×1
stringstream ×1
tolower ×1
toupper ×1