12

我意识到以下在 GCC 4.7 中编译得很好:

#include <memory>

int main() {
    std::shared_ptr<int> p;
    p = 0;
}

但是,没有来自int或来自的赋值运算符,也没有来自任何一个或任何一个int*的隐式构造函数。有一个构造函数,但该构造函数是显式的。我检查了标准库的实现,构造函数确实是显式的,并且看不到任何可疑的赋值运算符。intint*int*

该程序实际上是格式良好的还是 GCC 惹恼了我?

4

2 回答 2

16

这样做的原因是标准中的这个简短引用:

§4.10 [conv.ptr] p1

空指针常量是整数类型的整数常量表达式(5.19) 纯右值,其计算结果为零或类型的纯右值std::nullptr_t。[...] 整数类型的空指针常量可以转换为 prvalue 类型std::nullptr_t。[...]

std::shared_ptr并且具有来自的隐式构造函数的事实std::nullptr_t

§20.7.2.2 [util.smartptr.shared] p1

constexpr shared_ptr(nullptr_t) : shared_ptr() { }

这也允许像这样的奇怪:

#include <memory>

void f(std::shared_ptr<int>){}

int main(){
  f(42 - 42);
}

活生生的例子。

于 2012-08-09T17:19:39.737 回答
0

您只能将共享指针分配给共享指针的另一个实例。无法分配 shared_pointer 持有的类型。Afaik 这是运算符的唯一重载:

shared_ptr& operator=(const shared_ptr& r);

您正在做的是将 0(在这种情况下等于 NULL)分配给指针,而不是类型的值。此时您的类型甚至没有在代码中初始化。

于 2012-08-09T17:20:19.317 回答