将string_view转换为string是否合法

17

我的问题是受到stackoverflow上这个答案的启发,链接如下:https://dev59.com/tFYN5IYBdhLWcg3wCELa#48082010。引用如下:

问:如何将std::string_view转换为const char*

答:只需使用std::string(string_view_object).c_str()即可获得一个保证为空结尾的临时副本(并在行末清理它)。

不幸的是,它会构造一个新的string。我想知道是否可以简单地执行以下操作:

static_cast<string>(string_view_object).c_str()

现在,我的问题是:

  1. 这是否构建了一个新的字符串?

  2. 它是否保证返回一个以空字符结尾的 char 序列?

我有一个小代码片段进行演示。它似乎工作正常。(请参见 wandbox 结果

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

int main()
{
  std::string str{"0123456789"};
  std::string_view sv(str.c_str(), 5);

  std::cout << sv << std::endl;
  std::cout << static_cast<std::string>(sv) << std::endl;
  std::cout << strlen(static_cast<std::string>(sv).c_str()) << std::endl;
}

5
是的,这也会创建一个临时的 string 对象。我不知道你如何期望在没有副本的情况下将内容放置在 NUL 字符旁边。 - Ben Voigt
4
static_cast<T>(o)T(o)基本相同,都是将对象o转换为类型T - molbdnilo
2
请不要在有人回答了你的问题之后,添加一个验证信息来确认答案的正确性。这样会让那个回答者的努力成为无用功。如果对于你的问题已经得到满意的答案,请接受并采纳该回答。或者你可以发布另一个回答来提供自己的解决方案。SO是一个问答网站,问题应该放在问题区域,答案应该放在答案区域。 - StoryTeller - Unslander Monica
@故事讲述者 抱歉,我不是要否定其他人的努力。我以前从没回答过自己的问题,所以我的第一反应是通过编辑问题来发布答案。感谢您向我解释规则。 - MaxPlankton
1
没关系,我知道没有恶意。如果你自己找到了有用的东西并认为其他人也会受益,不要害怕回答自己的问题。事实上,这是非常鼓励的 :) - StoryTeller - Unslander Monica
2个回答

14

static_cast<std::string>(sv) 会调用期望任何类型可以转换为 std::string_view 的参数的 std::string::string 构造函数(更多细节)。因此,它仍然创建一个全新的 std::string 对象,进而保证了以空字符结尾的 char 序列。


1
我会这样表达:“是的和是的”(OP提出了两个问题)。 - Arne Vogel
2
一个字符串并不是以 null 结尾的。是 c_str() 函数在末尾添加了 null。 - Triskeldeian
std::string 的内部状态可能不包含以 null 结尾的字符串,但其接口提供了一个,即 data()c_str() 都保证返回指向以 null 结尾的 char 数组的指针。 - Mário Feroldi
@Triskeldeian C++11保证了内部数据是以空字符结尾的(不需要调用任何显式函数)。这包括对.data()的调用,该调用在C++03中不包含空字符结束符,也不需要.data()是连续的(在03之后进行了修复)。您可以... - ABaumstumpf

-3

检查static_cast<std::string>(sv)是否构造了一个新字符串的简单方法是验证它是否能够更改原始字符串。

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

int main()
{
  std::string str{"0123456789"};
  std::string_view sv = str;

  std::cout << sv << std::endl;
  static_cast<std::string>(sv)[0] = 'a';
  std::cout << static_cast<std::string>(sv) << std::endl;
} 

sv 保持不变,因此它创建了一个新的字符串。

wandbox. 上查看结果。


3
当涉及到字符串时,你需要小心那种“试试看”的方法。例如 const char* s = "hello"; 接着使用 const_cast 并尝试通过数组索引修改该字符串,有时候这种操作能够成功,但实际上其行为是未定义的。最好的方法是查看文档。 - Bathsheba

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接