最近、コンパイル エラーが発生したため、以下のコードに関して SE に質問を投稿しました。ムーブ コンストラクターまたはムーブ代入演算子を実装すると、デフォルトのコピー コンストラクターが削除されると、誰かが親切に答えてくれました。彼らはまた、次のstd::move()
ようなものを機能させるために を使用する必要があることを提案しました。
Image src(200, 200);
Image cpy = std::move(src);
この場合、移動代入演算子または移動コンストラクターを使用するという事実を明示する必要があるため、これは私には理にかなっています。この例では左辺値であり、これを で明示的に表現しない限りsrc
、実際にコンテンツを移動したいことをコンパイラに伝えることはできません。ただし、このコードにはさらに問題があります。cpy
std::move
Image cpy = src + src
以下のコピーは入れませんでしたが、operator +
次のタイプの単純なオーバーロード演算子です。
Image operator + (const Image &img) const {
Image tmp(std::min(w, img.w), std::min(h, img.h));
for (int j = 0; j < tmp.h; ++j) {
for (int i = 0; i < tmp.w; ++i) {
// accumulate the result of the two images
}
}
return tmp;
}
この特定のケースでは、演算子が の形式で一時変数を返し、tmp
その場合に に到達すると移動代入演算子がトリガーされると想定しますcpy = src + src
。src + src
の結果が左辺値であると言うのが正確かどうかはわかりません。実際には に返されるものtmp
が にtmp
コピー/代入されるためcpy
です。したがって、移動演算子が存在する前は、これによりデフォルトのコピー コンストラクターがトリガーされていました。しかし、この場合、移動コンストラクターを使用しないのはなぜでしょうか? 私もする必要があるようです:
Image cpy = std::move(src + src);
operator +
これを機能させるには、クラス Imageによって返される変数の xvalue を取得すると仮定しますか?
誰かがこれをよりよく理解するのを手伝ってくれませんか? 私が正しくないことを教えてください。
ありがとうございました。
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <fstream>
#include <cassert>
class Image
{
public:
Image() : w(512), h(512), d(NULL)
{
//printf("constructor default\n");
d = new float[w * h * 3];
memset(d, 0x0, sizeof(float) * w * h * 3);
}
Image(const unsigned int &_w, const unsigned int &_h) : w(_w), h(_h), d(NULL)
{
d = new float[w * h * 3];
memset(d, 0x0, sizeof(float) * w * h * 3);
}
// move constructor
Image(Image &&img) : w(0), h(0), d(NULL)
{
w = img.w;
h = img.h;
d = img.d;
img.d = NULL;
img.w = img.h = 0;
}
// move assignment operator
Image& operator = (Image &&img)
{
if (this != &img) {
if (d != NULL) delete [] d;
w = img.w, h = img.h;
d = img.d;
img.d = NULL;
img.w = img.h = 0;
}
return *this;
}
//~Image() { if (d != NULL) delete [] d; }
unsigned int w, h;
float *d;
};
int main(int argc, char **argv)
{
Image sample;// = readPPM("./lean.ppm");
Image res = sample;
return 0;
}