如果它是僅移動的,那麼最好的方法是按值取值,然後移動。
當v的類型可以是可複製或可移動的時,我將「最佳實踐」的狀態描述爲有點流暢,目前有不同的思想流派。但是,我認爲,這正被接受爲編寫最佳移動感知構造函數的方式,如您所需。
我會說,做你在這裏做了什麼,是的使用移動投射從右值初始化成員。
當您使用構造函數時,請嘗試利用copy-elision。例如,這個:
struct S {
S(std::vector<int> v) : m(std::move(v)) {}
private:
std::vector<int> m;
};
std::vector<int> create_vector()
{
std::vector<int> vec = // initialisation stuff
return vec;
}
int main()
{
S instance_of_s{create_vector()};
return 0;
}
......理想情況下,由於各種複製精度,理論上應該不復制任何東西。但是,當然,這是編譯器的依賴。
下面是一個演示這個的例子。
#include <iostream>
#include <memory>
#include <vector>
using namespace std;
class VectorWrapper
{
public:
VectorWrapper() : vec(){}
VectorWrapper(const VectorWrapper& other) : vec(other.vec){ cout << "COPY" << endl; }
VectorWrapper(VectorWrapper&& other) : vec(move(other.vec)){ cout << "MOVE" << endl; }
private:
vector<int> vec;
};
struct S
{
S(VectorWrapper v) : m(move(v)) {}
private:
VectorWrapper m;
};
int main()
{
S instance_of_s{VectorWrapper()};
return 0;
}
在GCC 4.7.2輸出爲:
MOVE
參考文獻:
http://cpptruths.blogspot.co.uk/2012/03/rvalue-references-in-constructor-when.html
http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/
(請注意,這是一系列文章,我錯過了以此開始的鏈接!)
平均有一個過載的最佳方法是按值重新移動。 [這個答案](http://stackoverflow.com/questions/15600499/how-to-pass-parameters-correctly/15600615#15600615)討論它。 – chris
如果您按值獲取參數,則您已擁有一份副本。所以沒有必要再複製它(就像'm(v)'會做的那樣)。 'm(std :: move(v))'並不意味着移動,但是如果可能的話它會移動。 – dyp
@DyP但事情是,如果你按價值進行論證,你可能沒有副本,對吧?它可能會被刪除或移動?我想知道是否同樣的事情適用於初始化成員。 – uk4321