2016-03-07 74 views
2

的在上下文下面的一個:移動資源出一個通用類

template <class T> 
struct MyStruct 
{ 
    T resource; 
    decltype(auto) getResource() 
    { 
     return std::move(resource); 
    }  
}; 

是我getResource方法做什麼,我希望它做的,即resource成員遷出之類的?我想在MyStruct將不使用任何更多的情況下使用它,這是確定從中「竊取」內存。

+4

如果你偷東西,你最好與一些更復雜的名稱堅持 - 據我可以告訴通過看** **弄人通常不期望修改。 – ixSci

+0

decltype(自動)是C++ 14 –

回答

2

隨着

template <class T> 
struct MyStruct 
{ 
    T resource; 
    decltype(auto) getResource() 
    { 
     return std::move(resource); 
    } 
}; 

decltype(auto)T&&。但T&&本身並不會竊取資源,(但允許它被隱含地竊取)。

另一種方法是

template <class T> 
struct MyStruct 
{ 
    T resource; 
    T takeResource() 
    { 
     return std::move(resource); 
    } 
}; 

這裏,一旦takeResource被調用時,資源已經轉移。

因此,例如

MyStruct<std::unique_ptr<int>> foo; foo.resource = std::make_unique<int>(42); 
*foo.get_resource() = 51; // No transfer ownership, just get a reference 
*foo.get_resource() = 69; // still works. 

*foo.get_resource() = 51; // Transfer ownership, and resource will be released here 
*foo.get_resource() = 69; // dereferencing nullptr -> UB. 
2

這一切都取決於什麼是T和移動構造函數是怎麼寫的。例如,如果它是一個int,它只是複製它。如果它是std::unique_ptr,它將完全符合你的期望。

爲了更好地理解看到這個例子請:

#include <iostream> 
#include <string> 
class copyable{ 
public: 
    copyable():x(0){}; 
    ~copyable()=default; 
    copyable(copyable const&)=default; 
    copyable(copyable&&)=default; 

    int x; 
}; 

class moveable{ 
public: 
    moveable():x(new int{0}){}; 
    ~moveable(){ 
     delete[] x; 
    }; 
    moveable(moveable const&)=delete; 
    moveable(moveable&& other){ 
     this->x=other.x; 
     other.x=nullptr; 
    }; 

    int* x; 
}; 

template <class T> 
struct MyStruct 
{ 
    T resource; 
    decltype(auto) getResource() 
    { 
     return std::move(resource); 
    }  
}; 

int main() 
{ 
    MyStruct<copyable> a; 
    std::cout << a.resource.x <<"\n"; 

    MyStruct<moveable> b; 
    std::cout << "address: "<< b.resource.x << "\tval: " << *b.resource.x <<"\n\n"; 

    auto temp_a=a.getResource(); 
    std::cout << temp_a.x <<"\n"; 

    auto temp_b=b.getResource(); 
    std::cout << "address: "<< temp_b.x << "\tval: " << *temp_b.x <<"\n\n"; 


    std::cout << a.resource.x <<"\n"; 
    std::cout << "address: "<< b.resource.x << "\tval: " << /* *b.resource.x << THIS IS UB */ "\n\n"; 

} 

輸出:

0 
address: 0x2d366f0 val: 0 

0 
address: 0x2d366f0 val: 0 

0 
address: 0 val: 

Live Demo

0

std::move自身不動,這是一個輕微的misnoma 。 std::move這裏只確保一個右值。你的類型T還需要有一個構造函數來允許實際移動它。

總而言之,你不能保證你的資源是不可複製的。

,如果你想明確誰擁有在特定的時間了得天獨厚的資源傳遞一個unique pointer左右。獨特的指針是通用的,如果你將設計細化到足夠長的時間,可能會成爲你最終實現的東西。

+0

的std :: uniuqe_ptr將在可能沒有針對OP –

+0

@HumamHelfawi'unique_ptr'不會在堆上分配內存是合適的情況下,堆分配內存。 'make_unique'可以。 – juanchopanza

+0

@juanchopanza似乎我錯過了什麼。你的意思是我可以使std :: unique_ptr指向堆棧分配的對象? –