从 C 字符串构造 std::string 与从另一个 std::string 构造 std::string 不一致

Inconsistency constructing std::string from C-string vs. from another std::string

本文关键字:string std 另一个 构造 不一致 字符串      更新时间:2023-10-16

为什么std::string构造函数根据构造的字符串类型产生不同的输出?

例如,请考虑以下C++代码:

#include <iostream>
#include <string>
int main() {
char cstyle[] = "01234567";
std::string std = "01234567";
std::cout << std::string(cstyle, 4) << std::endl;
std::cout << std::string(std, 4) << std::endl;
return 0;
}

这将产生以下输出:

0123
4567

我希望他们都生产0123,或者两者都产生4567,但我不希望一个产生0123,另一个产生4567

为什么会出现这种不一致?

编辑:这个问题不是关于调用哪个默认构造函数,或者它们是否做不同的事情。它们不同的事情,并调用不同的构造函数。这个问题关于他们为什么不做同样的事情。换句话说,这更像是一个哲学问题,而不是一个技术问题。

在每种情况下,都有一个带有和没有进一步整数参数的重载;我们可以认为它们是可选的。 对于来自const char*的构造函数,一个附加参数是大小(如果输入不是以 null 结尾的,则需要该参数(;如果你想要一个起始偏移量,你可以只写std::string(p+off,sz),所以把它作为参数提供是没有意义的。

但是,当复制另一个string对象时,std::string(s.data()+off,sz)是迂回且不安全的。 如果没有源对象,就不可能防止偏移量或显式大小使其溢出;从历史上看,data()并不总是(保证(以 null 终止,因此在没有大小的情况下,这种用法是不安全的。 因此,为类似复制的构造函数提供了起始偏移量和大小(按该顺序,因为这更自然(,如果您只提供一个,则它必须是偏移量。