标签: string-view

返回const std :: string的方法是否应该返回const std :: string_view?

假设我们在类中有一个简单的getter方法,该方法返回conststd::string成员的引用:

const std::string& getString() const noexcept { return someString; }
Run Code Online (Sandbox Code Playgroud)

随着std::string_viewC ++ 17 的问世,我想知道编写它是否具有任何优势:

const std::string_view getString() const noexcept { return someString; }
Run Code Online (Sandbox Code Playgroud)

一种方法比另一种方法有优点/缺点吗?显然(如果我错了,请纠正我),两种解决方案肯定会比这更好:

const char* getString() const noexcept { return someString.c_str(); }
Run Code Online (Sandbox Code Playgroud)

我已经看到了这个相关的问题,但是我要的是稍微不同的东西。

c++ string string-view c++17

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

从函数返回 string_view

我正在编写许多 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() …
Run Code Online (Sandbox Code Playgroud)

c++ string-view c++17

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

传递临时std :: string时的string_view行为

我只是遇到了一些误解:至少在libc ++实现中,std :: experimental :: string_view具有以下简洁的实现:

template <class _CharT, class _Traits....>
class basic_string_view {
public:
   typedef _CharT value_type;
   ...
   template <class _Allocator>
   basic_string_view(const basic_string<_CharT, _Traits, _Allocator>& str):
       __data(str.data()), __size(str.size())
   {
   }

private:
   const value_type* __data;
   size_type __size;
};
Run Code Online (Sandbox Code Playgroud)

这个实现是否意味着如果我们将rvalue表达式传递给这个构造函数,在构造之后使用__data时我们会得到未定义的行为?

c++ string c++11 fundamentals-ts string-view

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

string_view格式化流输出的实现

在实现C++ 1z std::basic_string_view以在较旧的编译器上使用它时,我遇到了流输出操作符重载的问题.基本上,它必须输出string_viewwhile 引用的内容而不依赖于任何存在的null-terminator(因为string_view不保证是以null终止的).

通常,编写重载operator<<非常容易,因为您可以依赖已经存在的重载,因此不需要使用SO中此问题中提到的 sentry对象.

但在这种情况下,没有预定义的重载来operator<<获取字符指针和长度(显然).因此,我std::string在当前的实现中创建了一个临时实例:

template< typename TChar, typename TTraits >
auto operator<<(::std::basic_ostream<TChar, TTraits>& p_os, basic_string_view<TChar, TTraits> p_v)
    -> ::std::basic_ostream<TChar, TTraits>&
{
    p_os << p_v.to_string(); // to_string() returns a ::std::string.
    return p_os;
}
Run Code Online (Sandbox Code Playgroud)

这是有效的,但我真的不喜欢我必须创建一个临时std::string实例的事实,因为这需要冗余地复制数据和动态内存的潜在用法.至少在我看来,这违背了使用轻量级引用类型的目的.

所以我的问题是:

在没有开销的情况下为string_view实现正确格式化输出的最佳方法是什么?


在研究时,我发现LLVM是这样的:(在这里找到)

// [string.view.io]
template<class _CharT, class _Traits>
basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os, basic_string_view<_CharT, _Traits> __sv)
{
    return _VSTD::__put_character_sequence(__os, …
Run Code Online (Sandbox Code Playgroud)

c++ string-view c++17

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

std::unordered_set 中的 std::string_view 和 std::string

假设您有一个std::unordered_set<std::string>.

您有一个std::string_view要在容器中搜索的对象。问题是,您不想std::string从您的 中创建 a std::string_view,因为这种首先违背了使用的目的std::string_view

不过,好像std::string_view应该可以作为key使用;应该有某种方式来比较std::string_viewand std::string,因为它们基本上代表同一件事。但是没有,无论如何都没有在 STL 中。

这是一个僵局,我是否被迫编写自己的比较对象std::string_viewstd::string与我的对象一起使用std::unordered_set

编辑:这个问题特定于 string_view 对象。“重复”问题不相关。正如预期的那样,我收到了一个独特问题的独特答案。

c++ stl unordered-set string-view c++17

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

连接 string_view 对象

我一直std::string_view在一些旧代码中添加 s 来表示配置参数等字符串,因为它提供了只读视图,由于不需要复制,速度更快。

string_view但是,由于operator+未定义,因此无法将两个连接在一起。我看到这个问题有几个答案表明它是一个疏忽,并且有一个建议添加它。但是,这是添加 astring和 a string_view,大概如果实现的话,生成的串联将是std::string

添加两个string_view也属于同一类别吗?如果不是,为什么不string_view支持添加两个?

样本

std::string_view s1{"concate"};
std::string_view s2{"nate"};
std::string_view s3{s1 + s2};
Run Code Online (Sandbox Code Playgroud)

这是错误

error: no match for 'operator+' (operand types are 'std::string_view' {aka 'std::basic_string_view<char>'} and 'std::string_view' {aka 'std::basic_string_view<char>'})
Run Code Online (Sandbox Code Playgroud)

c++ string-concatenation string-view c++17

10
推荐指数
3
解决办法
1万
查看次数

是否保证std :: string_view文字为空终止?

我知道,琐碎小事std::string_view不能保证会以null结尾。但是,我不知道std::string_view文字是否保证为空终止。

例如:

#include <string_view>

using namespace std::literals;

int main()
{
    auto my_sv = "hello"sv;
}
Run Code Online (Sandbox Code Playgroud)

C ++ 17或更高版本是否保证以my_sv.data()Null结尾?

===以下为更新===

以下全部来自n4820

  1. 根据5.13.5.14,字符串文字是空终止的。
  2. 根据5.13.8,用户定义的字符串字面量由字符串文字和自定义后缀组成。说,"hello"svhello是字符串文字,sv是后缀。
  3. 按照5.13.8.5,"hello"sv作为表单的一个呼叫被处理operator "" sv(str, len);为每5.13.5.14,str是空终止。
  4. 按照21.4.2.1,svdata()必须返回str

他们可以证明"hello"sv.data()C ++标准保证它可以为空终止吗?

c++ string standards string-view c++17

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

为什么string_view构造函数不接受一对迭代器

boost中的string_ref和GSL中的string_span都没有定义带有一对迭代器的构造函数.这个决定的原因是什么?

通常这不是什么大问题,我可以像这样创建string_ref:

boost::string_ref s(start, std::distance(start, finish));
Run Code Online (Sandbox Code Playgroud)

但我希望构造函数采用一对迭代器的原因是因为我的代码看起来像这样:

template<typename Type, typename Iterator>
void func(const Iterator& begin, const Iterator& end)
{
    Type s(begin, end);
    //do stuff with s
}
Run Code Online (Sandbox Code Playgroud)

目前,我可以这样称呼它:

func<std::string>(start, finish)
Run Code Online (Sandbox Code Playgroud)

我想将其更改为:

func<boost::string_ref>(start, finish) //compile error
Run Code Online (Sandbox Code Playgroud)

但是该代码将无法编译,因为缺少构造函数在string_ref中使用一对迭代器

c++ string-view string-span

7
推荐指数
2
解决办法
1556
查看次数

从一系列字符构建 string_view

虽然 aspan可以从范围构造,string_view但不能从字符范围构造。

因此,例如,需要以下代码:

// assume chars_span is a span of chars
std::cout << std::string_view(chars_span.data(), chars_span.size());
// or:
std::cout << std::string_view(chars_span.begin(), chars_span.end());
Run Code Online (Sandbox Code Playgroud)

而不是不支持的更简单的范围语法

std::cout << std::string_view(chars_span);
Run Code Online (Sandbox Code Playgroud)

是否有理由没有string_view接受一系列字符的构造函数,或者它只是被忽视或被认为不够重要?

c++ string-view c++20

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

std::basic_string_view&lt;T&gt; 和 std::span&lt;T&gt; 之间的区别

我正在解析二进制网络数据,我希望使该过程尽可能减少分配。但现在我意识到有两个非常相似的概念可能都足够适合我的情况,它们是std::basic_string_view<T>std::span<T>

所以我想知道。这两者之间有什么区别?使用其中一种比另一种有什么优势?一个明显的区别是可用性,std::basic_string_viewC++17 中已存在,而std::spanC++20 中已存在(但您可以使用“指南支持库”中的旧标准)。但还有别的事吗?应该如此,否则它们就不会同时进入标准。

c++ string-view guideline-support-library

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