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

时间:2014-01-05 19:24:42

标签: c++ string c++11 stl std

(在周日晚上思考)

在我编写的函数中,我倾向于依赖同一字符串的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 :我在这里谈的是理智的以空字符结尾的字符串,而不是std::basic_string特有的支持空字符串的伪字符串。 < / p>

问题重播:为什么std::string().c_str()指向内存时不应该?它应该是nullptr。与std::string().c_str("")不同,\0是一个空字符串,需要{{1}}跟踪它。所以它实际上指向有效的内存。 (如果您不理解字符串/指针是如何工作的,请不要费心回答。这需要一些类似C的理解。)

4 个答案:

答案 0 :(得分:6)

在以下表达式中:

const char* foo = "";

有一个空字符串but I do not see a null pointer。空C字符串是char [] char[0] = '\0',这就是全部。

const char*类型的空指针是一个不存在的字符串。

答案 1 :(得分:6)

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

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

答案 2 :(得分:2)

如果空字符串的c_str返回nullptr,那么这将无效:

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

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

答案 3 :(得分:2)

考虑C类型字符串(NULL终止字符串)

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

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