标签: string-view

如何使用 span 来包装命令行参数

即将推出的 C++20 的这种使用是否std::span正确并且没有开销来包装命令行参数?

#include <iostream>
#include <span>

int main(int argc, const char* argv[])
{
    for (auto s : std::span { argv, static_cast<std::size_t>(argc) })
      std::cout << s << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

如果它是正确的,我可以进一步使用 withstd::string_view吗?

c++ string-view c++20 std-span

2
推荐指数
1
解决办法
1532
查看次数

在 C++17 中引用 const 字符串的语义应该是什么?

有几种方法可以将文本信息传递给 C++ 中的函数:可以是 c-string/std::string、按值/按引用、左值/右值、常量/可变的。C++17 在标准库中添加了一个新类:std::string_view. string_view 的语义是提供没有所有权的只读文本信息。因此,如果您只需要读取一个字符串,您可以使用:

void read(const char*);        // if you need that in a c-style function or you don't care of the size
void read(const std::string&); // if you read the string without modification in C++98 - C++14
void read(std::string_view);   // if you read the string without modification in C++17
Run Code Online (Sandbox Code Playgroud)

我的问题是在 C++17 中void read(const std::string&)是否应该优先考虑任何情况void read(std::string_view)。假设不需要向后兼容性。

c++ string-view c++17

2
推荐指数
1
解决办法
82
查看次数

将 std::string 转换为 std::string_view 的时间复杂度

最小可重复示例:

using namespace std;

#include<string>
#include<string_view>
#include<iostream>

int main()
{
    string s = "someString";
    string_view sV = string_view(s);
    string_view sVTwo = string_view(begin(s), end(s));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

创建 string_view sV 的时间复杂度是否与字符串 s 中的字符数成线性关系,或者与字符串 s 的长度无关?同样,构造 sVTwo 的时间复杂度是线性的还是恒定的,取决于字符串中有多少个字符?

我感到困惑的原因是我无法分辨这里的哪些构造函数: https: //en.cppreference.com/w/cpp/string/basic_string_view/basic_string_view用于构造字符串。

c++ string string-view

2
推荐指数
1
解决办法
1648
查看次数

为什么 std::istream_iterator&lt; std::string_view &gt; 无法编译?

为什么 GCC 和 Clang 无法编译下面的代码片段(链接)?我想返回 s 的向量std::string_view,但显然无法string_view从 中提取 s stringstream

#include <iostream>
#include <sstream>
#include <string>
#include <string_view>
#include <vector>
#include <iterator>
#include <algorithm>
#include <ranges>


[[ nodiscard ]] std::vector< std::string_view >
tokenize( const std::string_view inputStr, const size_t expectedTokenCount )
{
    std::vector< std::string_view > foundTokens { };

    if ( inputStr.empty( ) ) [[ unlikely ]]
    {
        return foundTokens;
    }

    std::stringstream ss;
    ss << inputStr;

    foundTokens.reserve( expectedTokenCount );

    std::copy( std::istream_iterator< std::string_view >{ ss }, …
Run Code Online (Sandbox Code Playgroud)

c++ istream-iterator libstdc++ string-view

2
推荐指数
1
解决办法
219
查看次数

为什么 `std::string_view` 的实现没有不同?

给出以下代码,我们可以看到,std::string_view当字符串增长超出容量时,它就会失效(这里 SSO 最初生效,然后将内容放入堆上)

#include <iostream>
#include <cassert>
#include <string>

using std::cout;
using std::endl;

int main() {
    std::string s = "hi";
    std::string_view v = s;

    cout << v << endl;

    s = "this is a long long long string now";

    cout << v << endl;
}
Run Code Online (Sandbox Code Playgroud)

输出:

hi
#
Run Code Online (Sandbox Code Playgroud)

因此,如果我将 string_view 存储到字符串中,然后更改字符串的内容,我可能会遇到大麻烦。鉴于现有的实现,是否有可能std::string变得更智能string_view?哪个不会面临这样的缺点?我们可以存储一个指向字符串对象本身的指针,然后确定该字符串是否更多地处于 SSO 中并相应地工作。(虽然不确定这如何处理文字字符串,所以也许这就是为什么不这样做的原因? )

我知道这string_view类似于存储返回值,string::c_str()但考虑到我们有这个包装器,std::string我认为很多使用此功能的人不会遇到这个问题。大多数免责声明是为了确保所指向的内容std::string在范围内,但这完全是一个不同的问题。

c++ string-view c++17

2
推荐指数
1
解决办法
539
查看次数

字符串追加 string_view 意外结果

#include <iostream>
std::string_view return_string_view();
using namespace std;
int main()
{
  string got;
  auto peeked = return_string_view();
  got += peeked;
  cout << got << endl;
  return 0;
}
string_view return_string_view()
{
  string const s = string().assign( 2, 'x' );
  auto sv = string_view( s.c_str() );
  return sv;
}

Run Code Online (Sandbox Code Playgroud)

操作系统版本

Linux vm 5.19.0-45-generic #46-Ubuntu SMP PREEMPT_DYNAMIC Wed Jun 7 09:08:58 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux

Run Code Online (Sandbox Code Playgroud)

海湾合作委员会版本

Linux vm 5.19.0-45-generic #46-Ubuntu SMP PREEMPT_DYNAMIC Wed Jun 7 09:08:58 UTC 2023 x86_64 x86_64 x86_64 …
Run Code Online (Sandbox Code Playgroud)

c++ string-view

2
推荐指数
1
解决办法
109
查看次数

非空终止char数组的std :: string_view大小的差异

我正在使用不同编译器的std :: string_view,并注意到每个编译器在使用非null终止的char数组初始化std :: string_view时会打印出不同的大小.

似乎每个编译器在打开优化时打印出正确的大小,但在优化关闭时打印出错误的大小(GCC除外,它在两种情况下都打印出正确的大小).

我的问题是:为什么会这样?

码:

// test.cpp

#include <iostream>

#ifdef __MINGW32__
#include <experimental/string_view>
#elif _MSC_VER
#include <string_view>
#endif

int main()
{
    const char foo[3]{ 'f','o','o' };

#ifdef __MINGW32__
    std::experimental::string_view str_v{ foo };
#elif _MSC_VER
    std::string_view str_v{ foo };
#endif

    std::cout << sizeof(foo) << " " << str_v.size() << '\n';
}
Run Code Online (Sandbox Code Playgroud)

输出:Visual C++ 19.00.24619.0

3 5 // cl /Zi /std:c++latest /EHsc /nologo /W4 test.cpp
3 3 // cl /O2 /std:c++latest /EHsc /nologo /W4 test.cpp …
Run Code Online (Sandbox Code Playgroud)

c++ string-view c++17

1
推荐指数
1
解决办法
677
查看次数

为什么sv后缀引入的字符串不过期?

std::string_view使用临时初始化a是一个常见的错误std::string

using namespace std::literals;

std::string_view sv1 = "foo" ; // good
std::string_view sv2 = "bar"s; // bad: "foo"s will expire

std::cout << sv1 << "\n"       // outputs foo
          << sv2 << "\n";      // undefined behavior
Run Code Online (Sandbox Code Playgroud)

这是因为"bar"s,临时表达式std::string完整表达式的末尾被销毁了。

但是"foo"sv呢?

std::string_view sv3 = "baz"sv;
Run Code Online (Sandbox Code Playgroud)

当然这应该起作用,因为后缀sv否则是没有用的。但是,这与之"baz"s有何根本区别?换句话说,为什么引入的字符串"baz"sv不过期?

c++ language-lawyer string-view c++17

1
推荐指数
1
解决办法
105
查看次数

如何从预处理器#if 指令调用 constexpr 函数?

我想将宏定义为字符串,稍后在编译时包含基于字符串比较的代码:

#include <iostream>
#include <string_view>

constexpr bool strings_equal(char const * a, char const * b) {
    return std::string_view(a)==b;
}

#define FOO "bar"


int main() {
#if strings_equal( FOO, "bar") == 0
    std::cout << "got a bar!" << '\n';
#endif
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译这个

$ g++ -std=c++17 test.cpp -o my_test
Run Code Online (Sandbox Code Playgroud)

给出错误:

test.cpp:12:18: error: missing binary operator before token "("
   12 | #if strings_equal( FOO, "bar") == 0
      |                  ^
Run Code Online (Sandbox Code Playgroud)

编辑

看来#if指令是否在函数内部很重要,因为如果它在函数内部,我们可以用它替换它if constexpr (...) { ... }但是如果它在 …

c++ constexpr string-view c++17

1
推荐指数
1
解决办法
189
查看次数

如何在 C++ 中输入 std::string_view ?

这是输入(有点)std::string_view变量的正常方法:

#include <bits/stdc++.h>
using namespace std;
int main()
{
    string str; // Still have to use std::string class // Resulting in stack/heap allocation
    getline(cin, str);

    string_view view(str);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我想知道有什么方法可以直接输入std::string_view而不必使用字符串类(使用堆分配)???

[我肯定知道字符串文字(如“Hello”)在编译时直接存储在二进制代码中,而不会导致任何堆栈/堆分配......所以也许可以通过任何方式将字符串文字直接输入到 string_view 中???]

注意:我希望用户输入不是代码中的硬编码字符串!

c++ string string-view c++17 c++20

1
推荐指数
1
解决办法
122
查看次数

如果调用函数的特定重载,如何引发编译时错误?

根据https://en.cppreference.com/w/cpp/string/basic_string_view/basic_string_viewstd::basic_string_view类有 7 个重载的 ctor。我只关心其中的两个,因为现在我不在我的代码中使用其余的。

这些是我关心的实例:

constexpr basic_string_view( const CharT* s, size_type count );
constexpr basic_string_view( const CharT* s );
Run Code Online (Sandbox Code Playgroud)

我需要防止代码调用第二个代码(因为它可能导致非空终止缓冲区的缓冲区溢出)。

我有类似下面的内容:

#include <iostream>
#include <sstream>
#include <string>
#include <array>

void func( const std::string_view str )
{
    if ( str.empty( ) )
    {
        return;
    }

    std::stringstream ss;

    if ( str.back( ) == '\0' )
    {
        ss << str.data( );
    }
    else
    {
        ss << std::string{ str };
    }
}

int main()
{
    std::array<char, 20> buffer { }; …
Run Code Online (Sandbox Code Playgroud)

c++ constructor-overloading string-view

1
推荐指数
1
解决办法
63
查看次数

比较 std::string_view 和子字符串 string_view

假设我们有一个 string_view 和另一个 string_view,它是第一个 string_view 的子集:

using namespace std; // just to shorten the example...

string_view s{"abc def"};
auto t = s.substr(4);
auto u = s.substr(0, 4);

cout << *(s.begin() + 4) << "  " << *t.begin() << '\n';
cout << ((s.begin() + 4) == t.begin());
cout << (s.end() == t.end());
cout << ((s.begin() +5) == t.begin());
cout << ((s.begin() +5) == (t.begin() + 1));
cout << ((s.begin() + 4) == u.end()); // true
Run Code Online (Sandbox Code Playgroud)

所有比较都可以在 gcc (9 HEAD) 和 clang …

c++ std string-view c++17

0
推荐指数
1
解决办法
2737
查看次数

string_view 与 const char* 性能

一个std::string_view参数比const char*下面代码中的一个参数更好吗?

void func( const std::string_view str )
{
    std::istringstream iss( str.data( ) ); // str is passed to the ctor of istringstream


    std::size_t pos { };
    int num { std::stoi( str.data( ), &pos, 10 ) }; // and here it's passed to std::stoi
}

int main()
{
    std::array<char, 20> buffer { };
    std::cin.getline( buffer.data( ), 20 );
    func( buffer.data( ) );
}
Run Code Online (Sandbox Code Playgroud)

std::istringstreamctor 和都std::stoi需要 aconst std::string&作为参数。但我std::string_view使用其data()成员函数向他们传递一个对象。这是不好的做法吗?我应该回到 …

c++ c-strings stdstring micro-optimization string-view

0
推荐指数
1
解决办法
831
查看次数