还有一次这个问题,但相关的问题没有回答我的问题。
标准非常明确:
12.8复制和移动类对象,
§9
如果类X的定义没有显式地声明一个移动构造函数,那么当且仅当存在构造函数时,将默认将其声明为默认值 - X没有用户声明的拷贝构造函数,
- X没有用户声明的复制赋值运算符,
- X没有用户声明的移动赋值运算符,
- X没有用户声明的析构函数,以及
- 移动构造函数不会被隐式定义为已删除 [注意:当未隐式声明或显式提供移动构造函数时,否则将调用移动构造函数的表达式可能会调用复制构造函数。 - 结束说明]
所以,在注意到最后的“Note”之前,我预计这段代码会无法编译(虽然我知道,移动应该回退到复制):
#include <iostream>
using std::cout;
class c
{
public:
c() { cout << "c::c()\n"; }
c( std::initializer_list< int > ) { cout << "c::c( std::initializer_list )\n"; };
c( const c& ) { cout << "c::c( const c& )\n"; }
c& operator=( const c& ) { cout << "c& c::operator=( const c& )\n"; return *this; }
~c() { cout << "c::~c()\n"; }
void f() {}
};
void f( c&& cr ) { cout << "f()\n"; cr.f(); }
int main()
{
c x;
f( std::move( x ) );
return 0;
}
然后我在最后看到了这个注释,但我仍感到惊讶,上面的代码输出:
Ç:: C()
f()的
Ç::〜C()
请注意“缺少”c::c( const c& )
。然后我添加了
c( c&& ) = delete;
c& operator=( c&& ) = delete;
,结果仍然相同。
我在这里想念什么?
$ g++ --version
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.2) 5.4.0 20160609
编译器标志:-s -O0 -march=native -pthread -std=c++11 -Wall -Wextra -DNDEBUG
。
答案 0 :(得分:8)
你没有移动任何物体。
std::move
实际上非常令人困惑,因为它不会移动任何东西。只有移动构造函数或移动赋值运算符才能移动对象,std::move
所做的只是将l值引用(&
)转换为r值引用(&&
)。
移动构造函数,或者移动赋值运算符可以绑定到r-value-refernce(&&
)并窃取对象内容。
答案 1 :(得分:7)
示例中的var casper = require("casper").create();
casper.start();
casper.on('remote.message', function(message) {
console.log(message);
});
// first evaluate() to create the image
casper.thenEvaluate(function() {
// create original image to be copied
// in the canvas (mandatory to do this first step)
var originalImg = document.createElement('img');
originalImg.id = 'myoriginalimg';
originalImg.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAIAAACRXR/mAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AwLDiAQSszC7gAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAACAElEQVRYw+2WMYvbQBBGv5ndFegsdC6cTkWKFIEcpDkCqfLz3aQx5KqQ5lAXHRhHurW12pkUJsThDhLJyAlhXyWJWfHYmdkdIJFIJBKJRCIxJ3T+L8qT591f1yqBElgCqzxfGAOgi7HxfgvszvabqFUBlXNv8rxiXhmTEwHwqk2Mtcid93UI9RladprT26K4tfa1c5W1C2YHAAhAJ1IPQ8X8cRjQtvXFtI5OH7LsJssqYwoiR8QAAAGWRNfM18Ys+h5FMdnMjq2nyrlba2+y7KW1BWDpZxkYwBBZwFoLoBN5cG4XwoQ6M6OiXwDvi+Jdlr1yriQ6OtEJAJjIAhmRAi1RfThM0OJR0UugYq6sLU6cfukgIgCWqCCqrK2Yl5OSyKMyuMrzlTELZvec06mZI1owr4xZ5Xk5924tjMmJ3B8sY8ABOdHxSJtX62KM0+pi9KoBkN9FChAAr9rFOK/WDmi8b2LsRIIqAFV9Gnb8GFQ7kSbGxvvZO3EL1CL1MLSqw3Nmx9dBtVWth6EW2U5K4vh6FFkaUxpzxWwBftKMg2oL3Me46fv142Mtcphb6wBARKy9AjKijIiPx+mPeupVd6r3MX7q+3UIn/f7r5fZrR3g+35vjIooQEQB6FW96jfVB5EvIWz6fh3C5oyr+h8dbP6vMXDuoTmRSCQSiURiPN8BXZXzZJhVHqQAAAAASUVORK5CYII=";
document.body.appendChild(originalImg);
})
casper.then(function(){
casper.wait(1000);
})
// second evaluate() to create the canvas from the image
casper.thenEvaluate(function() {
// copy the original image in a canvas
var imgInInput = document.querySelector('#myoriginalimg');
var imageObj = new Image();
imageObj.src = imgInInput.getAttribute('src');
var canvas = document.createElement('canvas');
canvas.width = 50;
canvas.height = 50;
var context = canvas.getContext('2d');
context.drawImage(
imageObj,
0,
0,
canvas.width,
canvas.height,
0,
0,
canvas.width,
canvas.height
);
var imageData = context.getImageData(0, 0, 50, 50);
var data = imageData.data; // data of the current image
var pix = 0;
for(var i = 0; i < data.length; i += 4) {
pix++;
var red = data[i];
var green = data[i+1];
var blue = data[i+2];
var alpha = data[i+3];
data[i+3] = 255; // set transparency to null
data[i+1] = 255; // set green at maximum just for the test
console.log(
pix + "nth pixel" +
" red=" + red +
" green=" + green +
" blue=" + blue +
" alpha=" + alpha
);
}
// overwrite original image
context.putImageData(imageData, 0, 0);
// Create a <div> to put the canva in
var childDiv = document.createElement("div");
childDiv.appendChild(canvas);
// Create the parent <div>
var parentDiv = document.createElement("div");
parentDiv.setAttribute('id', 'outputimage');
parentDiv.setAttribute('style', 'position: absolute;z-index:9999');
document.body.insertBefore(parentDiv, document.body.firstChild);
childDiv.setAttribute('id', 'mydivid');
parentDiv.appendChild(childDiv);
});
casper.then(function() {
casper.capture("out.png");
casper.echo(casper.getHTML());
})
casper.run(function() {
this.exit();
});
参数是r值参考。这里的参考词很重要。它的行为有点类似于我们从c ++知道的平面旧引用,在c ++ 11在游戏中之前,在一个不调用任何构造函数的术语中......它只是&#34;指向&#34;到你传递的对象......
要调用移动构造函数(或执行其他交换)并使用引用,我们需要进一步转发引用,例如如下:
cr