簡體   English   中英

使用std :: pair或std :: tuple的移動語義

[英]Using move semantics with std::pair or std::tuple

假設你想利用移動語義,但你的一個可移動類需要成為std::pair 目的是創建一個函數,該函數返回一個std::pair ,可以將其視為rvalue並轉發。

但我無法看到如何做到這一點,除非對std::pair本身進行內部更改,以使其了解移動語義。

請考慮以下代碼:

struct Foo
{
 Foo() { }

 Foo(Foo&& f) { }

 private:

 Foo(const Foo& f) { } // do not allow copying
};

int main() 
{
 Foo f;
 std::pair<Foo, int> res = std::make_pair(f, 10); // fails due to private copy constructor
}

問題是std::make_pair以及std::pair構造函數本身需要兩個對象並嘗試制作它們的內部副本。 這導致它嘗試並調用復制構造函數。 但在我的例子中,我希望能夠新對移動res ,並確保不會創建副本。 除非std::pair本身在內部定義了以下構造函數,否則我認為這是不可能的:

pair(T1&& t1, T2&& t2) : first(std::move(t1)), second(std::move(t2))

但它沒有,至少在我使用的編譯器上沒有(gcc 4.3.2)。 這可能是因為我的編譯器是簡單地外的日期,而事實上新版本都會有這樣舉動感知構造。 但是我對移動語義的理解目前有點不穩定,所以我不確定我是否只是在這里忽略了一些東西。 那么,我是否正在努力實現,而不是實際重新實現std::pair 或者我的編譯器是否已過時?

但是,這不是將被調用的std::pair構造函數。 將調用std::pair移動構造函數,移動構造函數應該完全符合您的預期(N3126 20.3.5.2/6):

template<class U, class V> pair(pair<U, V>&& p);

效果:構造函數首先使用std::move(p.first)初始化,然后使用std::move(p.second)第二次初始化。

但是,您的示例應該失敗,因為在std::make_pair(f, 10); f是左值,需要明確move d,否則復制。 以下應該有效:

std::pair<Foo, int> res = std::make_pair(std::move(f), 10);

GCC 4.3.2必須沒有完整的實施。 pair(和tuple)應該有移動構造函數:

template<class U, class V> pair(U&& x, V&& y);
效果:構造函數首先使用std :: forward(x)進行初始化,然后使用std :: forward(y)進行第二次初始化。
template<class U, class V> pair(pair<U, V>&& p);
效果:構造函數首先使用std :: move(p.first)進行初始化,然后使用std :: move(p.second)進行第二次初始化。

(來自n3126中的[pairs.pair])

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM