如何将rvalue生命周期延长到我的自定义容器生命周期?

时间:2016-05-13 05:08:54

标签: c++ c++11

让我有一个自定义包装容器。我想这样使用它:

double d = 3.14;
MyContainer<std::vector<int>> pointer = new std::vector<int>();
MyContainer<std::string> rvalue = std::string("foo");
MyContainer<int> rvalue2 = 5 + 8;
MyContainer<double> lvalue = d;

我不想存储rvalues的副本(引用是可以的)。 Rvalue引用允许我这样做:

std::string string1 = "foo";
std::string string2 = "bar";
std::string&& string3 = string1 + string2;
string3 += "test";

基本上我想将rvalues的生命周期延长到容器的生命周期。但是,当我这样做时:

template<class T>
class MyContainer {
public:
    MyContainer(T&& obj) : object(obj) {}
    T&& object
    ...
};
...
MyContaier<std::string> container = MyContainer(std::string("foo"));

我收到错误(无法将'std :: string'左值绑定到'std :: string&amp;&amp;')。这个例子略有不同,但我只是想了解一个总的想法。我怎么能避免这个?

1 个答案:

答案 0 :(得分:0)

除了您的代码有多个拼写错误和语法错误之外,从技术上来说,没有任何东西可以阻止您使用std::string的右值引用(尽管您的赋值/构造函数调用不正确)。保持T&amp;&amp;作为成员变量不像你认为的那样工作。一旦到达下一个序列点,存储对过期右值的引用然后访问它将是UB。

这是一个带有rvalue引用和左值引用的构造函数的工作示例。如果你想“拥有”它,你需要在你的对象中有一个实际的实例。从技术上讲,您无法延长到期右值的生命周期;你只能构建一些可以重用它的东西(希望能偷走一些昂贵的内脏)。希望这会有所帮助。

#include <utility>
#include <string>
#include <iostream>

template<class T>
class MyContainer {
public:

    // makes a copy from an lvalue reference
    MyContainer(const T& obj)
        : object(obj) {
    }

    // moves from an rvalue reference
    MyContainer(T&& obj)
        : object(std::move(obj)) {
    }

    MyContainer& operator=(const T& obj) {
        object = obj;
    }

    MyContainer& operator=(T&& obj) {
        object = std::move(obj);
    }

    T object;
};

int main() {

    MyContainer<std::string> container = std::string("foo");
    std::cout << container.object;
}