2016-03-07 72 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指向堆栈分配的对象? –