为什么 empty() std::basic_string c_str() 不是 nullptr?

Why an empty() std::basic_string c_str() is not nullptr?

本文关键字:str 不是 nullptr basic empty std 为什么 string      更新时间:2023-10-16

(在星期天晚上思考)

在我编写的函数中,我倾向于依赖同一字符串的const char*和模板化内联const std::basic_string<>&变体。但我真的很好奇为什么空字符串的c_str()不是nullptr.

大多数C++程序员现在都忽略const char*指针作为 C 代码,但我认为它非常C++,因为字符串null终止和连续的,并将继续如此。但是,如果您使用自定义分配器,那么您使用const std::string&参数编写的所有代码都是毫无意义的(除非仅标头)。

因此,您真正的选择(如果您想用途广泛)是老式字符指针或内联模板化函数,这些函数可以通过自定义分配器或特征支持各种std::basic_string。这会强制您内联模板化函数,因为您无法预先正确预测模板参数。

现在我的问题是为什么空字符串不返回 c_str() 的 nullptr?作为字符串函数中的最低公分母,特别是对于只读访问,是const char*而不是模板化因此约束的const std::string&。返回指向任何内容的指针,尤其是当没有进行字符串赋值时......在我看来很奇怪。

还是我太疯了,不能这样做?始终担心const char*和模板化的const std::basic_string<char, ..., ...>&对应物。如果std::string().c_str()在哪里nullptr,我不会担心。但我自己必须防范空字符串,因为c_str()std::basic_string不可靠。

PS:我知道老式字符串函数在与空指针一起使用时会崩溃,但是在任何地方使用字符串之前,可以轻松测试有效的指针和非空的第一个字符。

PPS:我在这里说的是理智的以 null 结尾的字符串,而不是std::basic_string特别支持的包含 null 的伪字符串。

问题改写:为什么std::string().c_str()指向内存,而不应该指向内存?应该是nullptr.与std::string().c_str("")不同,它是一个空字符串,需要一个尾随它的。所以它实际上指向有效内存。(如果您不了解字符串/指针的工作原理,请不要费心回答。这需要一些类似 C 的理解。

std::string的默认构造函数将构造一个空字符串。

如果没有相应的有效 C 字符串,则无法构造std::string对象。std::string()等效于std::string("")因此std::string::c_str()将始终返回有效指针,并且不应返回空指针。

在以下表达式中:

const char* foo = "";

有一个空字符串,但我没有看到空指针。空的 C 字符串是带有char[0] = ''char [],仅此而已。

具有const char*类型的 null 指针是不存在的字符串。

如果空字符串的c_str返回nullptr,则这是无效的:

const char* str1 = "";
std::string str2 = "";
const char* str2_c = str2.c_str();
assert(strcmp(str1, str2_c) == 0);

对我来说,这似乎是一个有缺陷的界面。两个空字符串应该相等。

考虑一个C类型字符串(以NULL 结尾的字符串)

const char * str1 = "";
const char * str2 = nullptr;
  • 第一个实现是一个大小为 0 大小的 NULL 终止字符数组。
  • 第二个只是初始化为 NULL 的字符指针。

如果std::string().c_str()返回一个nullptr那将是完全错误的,因为它是一个模板C++字符串,相当于一个 NULL 终止的 0 大小的 C 字符串。