(在周日晚上思考)
在我编写的函数中,我倾向于依赖同一字符串的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的理解。)
答案 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;
如果std::string().c_str()
要返回nullptr
,那么它将是完全错误的,因为它的模板C ++字符串等效于NULL终止的0大小的C字符串。