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

新手上路,请多包涵

使用带有标志 -std=c++17 的 gcc-7.1 编译,以下程序会引发错误:

 #include <string_view>
void foo(const char* cstr) {}
void bar(std::string_view str){
    foo(str);
}

错误信息是

In function 'void bar(std::string_view)':
error: cannot convert 'std::string_view {aka std::basic_string_view<char>}' to 'const char*' for argument '1' to 'void foo(const char*)'
 foo(str);

我很惊讶没有转换为 const char* 因为其他库(abseil,bde)提供类似的 string_view 隐式转换为 const char* 的类。

原文由 Justin Raymond 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 2.1k
2 个回答

std::string_view 不提供到 const char* 的转换,因为 它不存储以 null 结尾的字符串。它基本上存储了指向第一个元素的指针和字符串的长度。这意味着您不能将其传递给期望以空字符结尾的字符串的函数,例如 foo (您还要如何获得大小?),该函数需要 const char* 等等决定不值得。

如果您确定您的视图中有一个以 null 结尾的字符串,则可以使用 std::string_view::data

如果你不是,你应该重新考虑是否首先使用 std::string_view 是一个好主意,因为如果你想要一个有保证的以 null 结尾的字符串 std::string 是你想要的。对于单行,您可以使用 std::string(object).data()注意:返回值指向一个 临时std::string 实例,该实例将在表达式结束后被销毁!)。

原文由 Rakete1111 发布,翻译遵循 CC BY-SA 4.0 许可协议

只需执行 std::string(string_view_object).c_str() 即可获得有保证的空终止临时副本(并在行尾清理它)。

这是必需的,因为字符串视图不保证空终止。例如,您可以查看较长缓冲区的中间。

如果这个用例很昂贵并且您已经证明它是一个瓶颈,您可以编写一个增强的 string_view 来跟踪它是否为空终止(基本上,如果它是从原始构建的 char const* )。

然后,您可以编写一个辅助类型,该类型采用增强的 string_view 并将其复制到 std::string 或存储增强的 string_view 直接,并具有隐式转换to- char const* 返回正确的空终止缓冲区。

然后在代码库中的任何地方使用该增强的帮助器类型,而不是 string_view ,可能还会增加字符串视图与 std 字符串的交互,以捕捉您的视图到达 std 字符串缓冲区末尾的情况.

但实际上,这可能是矫枉过正。

更好的方法可能是重写采用 const char* 的 API 以采用 string_view

原文由 Yakk - Adam Nevraumont 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题