我正在GCC 5中扫描// set default color
var hex = 0x00ff00;
var u,v,xx,yy,ii;
// initialise arrow bases
var lines = new THREE.Geometry();
// loop through
Geometry[i].vertices.forEach(function(point,j)
{
// rescale
xx = Math.floor((point.x-data[i].x0)/data[i].dx);
yy = Math.floor((point.y-data[i].y0)/data[i].dy);
ii = data[i].nx*yy+xx;
u = data[i].frame[data[i].xvec][ii]*data[i].scale;
v = data[i].frame[data[i].yvec][ii]*data[i].scale;
lines.vertices.push(
new THREE.Vector3(point.x+data[i].dx/2, point.y+data[i].dy/2,1),
new THREE.Vector3(point.x+data[i].dx/2+u, point.y+data[i].dy/2+v,1)
);
});
var mat = new THREE.LineBasicMaterial({color:hex})
line[i] = new THREE.LineSegments( lines, material);
scene.add(line[i]);
实施,我看到以下内容:
shared_ptr
我的问题是为什么在交换之前临时的附加移动构造?我假设编译将删除任何额外的开销 - 但为什么不调用 __shared_ptr&
operator=(__shared_ptr&& __r) noexcept
{
__shared_ptr(std::move(__r)).swap(*this);
return *this;
}
?我有什么聪明的副作用吗?
我看到类中的其他函数也使用相同的模式实现,我可以理解接受const引用但是rvalue引用的情况吗?
答案 0 :(得分:7)
首先,这就是标准所说的内容,海湾合作委员会只是遵循了这一点。
这样,赋值运算符的后置条件为__r.empty()
,这是你的建议无法实现的,因此按照你的建议实现它会对标准所说的产生不同的影响,因此不符合要求。
即。这个断言成立:
auto p1 = std::make_shared<int>(1);
auto p2 = std::make_shared<int>(2);
p1 = std::move(p2);
assert( !p2 );
&#34;聪明的副作用&#34;是你创建一个新的空 shared_ptr,它在交换后最终保持旧值*this
,然后超出范围。这意味着*this
的旧值不会在__r
中结束。
答案 1 :(得分:1)
因为我们需要在引用的rvalue上调用析构函数来减少实例数。
答案 2 :(得分:1)
通过将__r
的内容移动到作为函数return
销毁的临时内容中,确保移出的对象__r
所指的是剩下的在空旷的状态。我猜他们想把这个逻辑放在一个地方,移动构造函数,看起来像这样。
__shared_ptr(__shared_ptr&& __r) noexcept
: _M_ptr(__r._M_ptr), _M_refcount()
{
_M_refcount._M_swap(__r._M_refcount);
__r._M_ptr = 0;
}
就个人而言,我更喜欢以下实施,据我所知,这是相同的。
widget&
operator=(widget&& other) noexcept
{
widget temp {};
swap(*this, temp);
swap(*this, other);
return *this;
}
可以使用像这样实现的移动构造函数来补充它。
widget(widget&& other) noexcept : widget {}
{
swap(*this, other);
}
我假设有一个
void
swap(widget&, widget&) noexcept;
ADL可以找到的重载以及widget
的默认构造函数为noexcept
。