我正在尝试使用现代字符串处理方法(如std::string_view
或GSL'sstring_span
)与将字符串作为空终止的 C API(DBus)进行交互const char*
,例如
DBusMessage* dbus_message_new_method_call(
const char* destination,
const char* path,
const char* iface,
const char* method
)
string_view
并且string_span
不保证它们的内容是空终止的——因为跨度是(char* start, ptrdiff_t length)
对的,这在很大程度上是重点。但是 GSL 也提供了一个zstring_view
,它保证是空终止的。周围的评论zstring_span
表明它是专为处理遗留 API 和 C API 而设计的,但我一开始使用它就遇到了几个症结:
将字符串文字表示为 a
string_span
很简单:cstring_span<> bar = "easy peasy";
但是将一个表示为 a
zstring_span
需要您将文字包装在辅助函数中:czstring_span<> foo = ensure_z("odd");
这使得声明更加嘈杂,而且文字(保证以 null 结尾)不能隐式转换为 a 似乎也很奇怪
zstring_span
。ensure_z()
也不是constexpr
,不像string_span
.有一个类似的奇怪之处
std::string
,它可以隐式转换为string_span
,但不是zstring_span
,尽管std::string::data()
自 C++11 以来已保证返回一个以空值结尾的序列。同样,您必须致电ensure_z()
:zstring_span<> to_zspan(std::string& s) { return ensure_z(s); }
似乎存在一些 const 正确性问题。上述工作,但
czstring_span<> to_czspan(const std::string& s) { return ensure_z(s); }
编译失败,出现关于无法转换为的
span<char, ...>
错误span<const char, ...>
这一点比其他点小,但返回 a 的成员函数
char*
(您可以将其提供给像 DBus 这样的 C API)被调用assume_z()
。当构造函数期望一个以空值结尾的范围时,会假设什么?zstring_span
如果zstring_span
设计为“将零终止跨度转换为遗留字符串”,为什么在这里使用它看起来如此麻烦?我在滥用它吗?有什么我忽略的吗?