如何将右值生存期扩展到自定义容器生存期

How do I extend rvalue lifetime to my custom container lifetime?

本文关键字:生存期 扩展到 自定义      更新时间:2023-10-16

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

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;

我不想存储右值的副本(引用是可以的)。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&")。这个例子略有不同,但我只是想了解一个大致的想法。我该如何避免这种情况?

除了您的代码有多个拼写错误和语法错误外,在技术上没有任何东西可以阻止您获取std::string的右值引用(尽管您的赋值/构造函数调用不正确)。保持T&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;
}