将资源移出通用类

时间:2016-03-07 08:08:58

标签: c++ c++14

在下面的背景下:

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

是我的getResource方法做了我期望它做的事情,即将resource成员移出课堂?我希望在MyStruct不再使用radiobutton的情况下使用它,并且可以&#34;窃取&#34;记忆吧。

3 个答案:

答案 0 :(得分: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

答案 1 :(得分: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 :(得分:0)

std::move不会自行移动,这是一个轻微的误解。 std::move此处仅确保rvalue。你的Type T还需要一个构造函数来允许实际移动它。

总而言之,您无法确保不会复制您的资源。

如果您想明确在某个时间拥有唯一资源的人,请传递unique pointer。独特的指针是通用的,如果你在足够长的时间内完善你的设计,它可能就是你最终实现的东西。