让我有一个自定义包装容器。我想这样使用它:
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;')。这个例子略有不同,但我只是想了解一个总的想法。我怎么能避免这个?
答案 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;
}