为什么可以将nullptr分配给std :: string?

Ear*_*rlz 7 c++ string standards c++11

所以今天我写了一个相当难以找到的bug,我将std :: string初始化为nullptr(不是指向std :: string的指针,而是值本身).我发现显然只能在C++ 11或更高版本中使用clang.

#include <string>
#include <iostream>

using namespace std;
class Meh{
    int x;
};
class Foo
{
private:
  std::string x=nullptr;
  Meh y=nullptr; //remove this line and it compiles
public:
  std::string z=nullptr;
};

int main(void)
{
    Foo f;
    cout << f.z;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我尝试将nullptr分配给一个类的随机实例,但它不起作用.字符串中有什么神奇之处可以让它工作,这种甚至是有效的语法?我假设在这种情况下我会遇到类型转换错误.

作为参考我用这个编译:

clang++ test.cpp -O3 -g -fno-inline -std=c++11 -Wall
Run Code Online (Sandbox Code Playgroud)

它没有给出任何形式的警告,但如果不使用C++ 11则会出错

Dan*_*rey 14

这只是因为存在构造函数(链接中的数字(5))和赋值运算符(链接中的数字(3)),因为std::string它接受a const char*,因此nullptr匹配.

在C++ 11之前(以及之前nullptr),当您尝试从0或构造时出现同样的问题NULL.所有这些情况都是非法的并导致未定义的行为,尽管过去至少有一个STL(RogueWave?)接受它并生成一个空字符串.

  • 也许标准应该添加一个删除的重载接受`nullptr` ... (11认同)
  • 值得注意的是,这是Undefined Behavior™ (6认同)
  • 我不认为这回答了“为什么”的问题,只是回答了“如何”的不同且没有被问到的问题。*为什么*是没有充分的理由,这是一个设计错误/疏忽。`std::basic_string` 是一个非常复杂的野兽,但大多数复杂性都与或多或少无用的东西有关;恕我直言,稍微增加一点安全性就值得稍微增加复杂性。 (2认同)