为什么std::string str(nullptr)和std::string str=nullptr是错的?有人能详细解释一下原因吗?
std::string str(nullptr)
std::string str=nullptr
k3bvogb11#
这样的例子可以编译,因为有一个std::string(const char*)构造函数可以接受以空结尾的字符串,这是在C中存储字符串的标准版本。此外,数组急切地衰减为指针,以便允许像std::string("Ahoj")这样的代码编译。这是错误的,因为构造函数需要一个有效的以null结尾的字符串,尽管您的示例已编译,但其行为未定义。类似地,std::string str(0);也可以工作,但也是未定义的,因为字面值零可以隐式转换为指针,因为它被用作nullptr-NULL的C11之前的版本。C23通过addingbasic_string( std::nullptr_t ) = delete;构造函数修复了这个问题,使所有示例都有nullptr或0编译时错误。
std::string(const char*)
std::string("Ahoj")
std::string str(0);
nullptr
NULL
basic_string( std::nullptr_t ) = delete;
0
**编辑:**我最初声称std::logic_error将被抛出,@François Andrieux纠正了我。
std::logic_error
iszxjhcz2#
当你写std::string str的时候,你是在声明一个字符串。nullptr是一个pointer value。如果你有一个字符串指针,你可以这样做。但是,如果只使用一个直的std::string,这是没有意义的。我猜你来自Java或C#,在那里,所有幕后的对象都是秘密的指针/引用。所以当你写String str时,你会把它初始化为null(或该语言的等价物)。但在C中,没有什么是指针,除非你显式地声明它是这样的(除非你知道你真的需要一个指针,否则你不应该这样做)。这意味着,C中的std::string(如int或std::vector或...)将 * 总是 * 有一个值。
std::string str
std::string
String str
null
int
std::vector
2条答案
按热度按时间k3bvogb11#
这样的例子可以编译,因为有一个
std::string(const char*)
构造函数可以接受以空结尾的字符串,这是在C中存储字符串的标准版本。此外,数组急切地衰减为指针,以便允许像std::string("Ahoj")
这样的代码编译。这是错误的,因为构造函数需要一个有效的以null结尾的字符串,尽管您的示例已编译,但其行为未定义。
类似地,
std::string str(0);
也可以工作,但也是未定义的,因为字面值零可以隐式转换为指针,因为它被用作nullptr
-NULL
的C11之前的版本。C23通过adding
basic_string( std::nullptr_t ) = delete;
构造函数修复了这个问题,使所有示例都有nullptr
或0
编译时错误。**编辑:**我最初声称
std::logic_error
将被抛出,@François Andrieux纠正了我。iszxjhcz2#
当你写
std::string str
的时候,你是在声明一个字符串。nullptr
是一个pointer value。如果你有一个字符串指针,你可以这样做。
但是,如果只使用一个直的
std::string
,这是没有意义的。我猜你来自Java或C#,在那里,所有幕后的对象都是秘密的指针/引用。所以当你写
String str
时,你会把它初始化为null
(或该语言的等价物)。但在C中,没有什么是指针,除非你显式地声明它是这样的(除非你知道你真的需要一个指针,否则你不应该这样做)。这意味着,C中的
std::string
(如int
或std::vector
或...)将 * 总是 * 有一个值。