2

我的代码中有一些部分广泛使用了字符串视图。在任何地方都使用是不可思议的std::string,并且char const*由于存在关联容器、许多比较和此类操作,这些操作很难用纯原始字符串进行。

但是,有一个地方最终会处理 C API,它需要以 null 结尾的字符串:

auto sv = std::string_view{/* ... */};
c_api(sv.data());

虽然这在我的情况下工作正常,但我想确保一切正常并断言字符串以空值结尾,因为我的系统构造字符串视图并将其发送到那里不会使用子字符串视图,并且会从字符串文字或std::string. 我知道我会没事的。

然而问题是另一个程序员可能不知道所有这些并尝试substr在字符串视图上使用,或者发送一个非空终止的字符串。非空终止的字符串是不好的,因为它会导致未定义的行为,但字符串视图中的子字符串更糟糕,因为发送到 C API 时不会应用上限,并且不会调用未定义的行为,但会而是引入了一个非常难以发现的带有意外行为的错误。

所以我想用一个断言来传达这一点:

auto sv = std::string_view{/* ... */};
assert(*(sv.data() + sv.length()) == '\0'); // Yay?
c_api(sv.data());

但我发现它不完整且容易出错,因为它可能会超出空终止字符串的范围。

有没有办法安全地断言字符串视图确实是空终止的?

4

1 回答 1

2

这可能会很痛苦,但我会写我自己的string_view,保证会被空终止。

因为 astring_view可以像这样构造

char array[3] = {'B', 'a', 'r'};
std::string_view array_v(array, sizeof array);

测试

*(sv.data() + sv.length()) == '\0'

在这种情况下是未定义的行为,因为最后一个有效索引是2但您访问3. std::string_view需要公开它不知道的信息才能让你这样做,因为它不能,所以你不能可靠地知道。

于 2019-10-14T16:11:43.863 回答