我正在研究一些最终也需要调用操作系统级 C 代码的 C++ 代码,例如scandir。
我想对大部分代码库使用 C++,这(对我而言)意味着我主要使用 std::string 而不是 char 指针。
我有一个接受 string_view 的方法,因此我可以传入 std::string 和 char*,具体取决于 C++ 或“C 互操作”代码是否需要调用它:
std::optional<std::vector<FileInfo>> scan_directory(const std::string_view directory)
{
if (directory.empty()) {
return {};
}
struct dirent **namelist;
int num = scandir(directory.data(), &namelist, nullptr, nullptr);
[...]
}
注意data()
这里的调用,因为 scandir 需要一个const char *
. 现在,我看到了这个注释:
与 std::basic_string::data() 和字符串字面量不同,data() 可能返回指向非空终止缓冲区的指针。因此,将 data() 传递给仅采用 const CharT* 并期望以空字符结尾的字符串的例程通常是错误的。
这让我想到:有没有更好/更安全的方法?我知道在实践中,调用者将以空字符结尾的字符串,但是当我已经意识到这里存在潜在问题时,我不想在以后创建一个难以诊断的错误。虽然我猜已经不能保证 char* 是空终止的,所以我不会让情况变得更糟。
不过,好奇是否有更好的选择。
- 我应该检查 string_view 是否有空终止符,如果不存在,创建一个
char[directory.size() + 1]{0}
并自己复制字符? - 或者创建两个重载,一个采用 std::string,另一个采用 const char*?
我g++ (GCC) 10.2.1 20201016 (Red Hat 10.2.1-6)
通过 CMake 的set(CMAKE_CXX_STANDARD 20)
.