在api中使用std :: string_view,期望null终止字符串

时间:2016-12-22 15:46:05

标签: c++ c++17

我有一个方法,它接受std::string_view并使用函数,它以null终止字符串作为参数。例如:

void stringFunc(std::experimental::string_view str) {
    some_c_library_func(/* Expects null terminated string */);
}

问题是,处理这种情况的正确方法是什么? str.to_string().c_str()是唯一的选择吗?我真的想在这个方法中使用std::string_view,因为我在其中传递了不同类型的字符串。

4 个答案:

答案 0 :(得分:13)

我通过创建名为string_view的备用zstring_view类来解决此问题。它是私有地继承自string_view并包含其大部分接口。

主要区别在于无法从zstring_view创建string_view。此外,任何从末尾删除元素的string_view API都不是界面的一部分,或者它们返回string_view而不是zstring_view

可以从任何以NUL结尾的字符串源创建它们:std::string,依此类推。我甚至为它们创建了特殊的用户定义的文字后缀:_zsv

这个想法是,只要你不手动将非NUL终止的字符串放入zstring_view,所有zstring_view都应该以NUL终止。与std::string类似,NUL字符不是字符串大小的一部分,但它是那里

我发现它对于处理C接口非常有用。

答案 1 :(得分:6)

您无法通过std::string_view更改字符串。因此,您无法添加终止'\0'字符。因此,您需要将字符串复制到其他位置以添加'\0' - 终止符。如果字符串足够短,可以通过将字符串放在堆栈上来避免堆分配。如果您知道,std::string_view是以空字符结尾的字符串的一部分,那么您可以检查,如果结尾的字符是'\0'字符,并在这种情况下避免复制。除此之外,我没有看到更多的优化空间。

答案 2 :(得分:5)

您当然不应在data上致电std::experimental::string_view

  

与basic_string :: data()和字符串文字不同,data()可能返回一个   指向非空终止缓冲区的指针。

请致电to_stringc_str

void stringFunc(std::experimental::string_view str) {
    some_c_library_func(str.to_string().c_str());
}

或:

void stringFunc(std::experimental::string_view str) {
    std::string real_str(str);
    some_c_library_func(real_str.c_str());
}

答案 3 :(得分:0)

在某些情况下,C-stype 函数有重载,它接受字符串的长度作为单独的参数。

例如而不是使用 strcasesmp() 值得切换到 strncasecmp()。 当然,在这种特殊情况下,如果字符串不相等,但前 n 个字符相等,则需要实现额外的逻辑。

但它可能是为字符串视图编写自定义类的不错选择。