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

时间:2018-01-03 16:34:16

标签: c++ string c++17 string-view

使用标记为-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*

3 个答案:

答案 0 :(得分:21)

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

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

如果这个用例很昂贵并且你已经证明它是一个瓶子,你可以编写一个扩充的string_view来跟踪它是否为空终止(基本上,如果它是从原始{{1}构造的})。

然后你可以编写一个辅助类型来获取这个扩充的char const*,并将其复制到string_view或直接存储扩充的std::string,并具有隐式的转换为{ {1}}返回正确的以null结尾的缓冲区。

然后在代码库中的任何地方使用该扩充的帮助器类型而不是string_view,可能会增加字符串视图与std字符串的交互,以捕获具有到std字符串末尾的视图的情况缓冲液中。

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

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

答案 1 :(得分:17)

std::string_view未向const char*提供转化,因为不存储以空字符结尾的字符串。它基本上存储了指向第一个元素的指针和字符串的长度。这意味着你不能将它传递给一个期望以空字符结尾的字符串的函数,比如foo(你还有什么方法可以得到大小?),它需要const char*,所以决定这不值得。

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

如果你不是,你应该重新考虑首先使用std::string_view是否是个好主意,因为如果你想要一个保证以空值终止的字符串std::string就是你想要的。对于单行,您可以使用std::string(object).data()

答案 2 :(得分:4)

您可以拨打foo(std::string(str).c_str())