假设我们有一个嵌入另一个参数的类,它必须支持复制和移动.让我们假设 - 在某些情况下 - 需要以某种方式获得内在价值.
一种典型的方法可以是这样的:
template<class T>
class wrapper
{
public:
wrapper() :val() {}
wrapper(T s) :val(std::move(s)) {}
wrapper(const wrapper& s) :val(s.val) {}
wrapper(wrapper&& s) :val(std::move(s.val)) {}
wrapper& operator=(wrapper s) { val = std::move(s.val); return *this; }
T value() const { return val; }
private:
T val;
};
Run Code Online (Sandbox Code Playgroud)
这不是唯一的方法,可能没有必要说明复制和移动,但让它们成为现实.
重点是另一个:假设T-in ceratin实例 - 本身就是一个复制/可移动的类.当然,wrapper::value()返回T的副本.
现在假设返回的T必须作为参数进入另一个调用,并且包含的包装器是临时的.
更简单的模拟是
calledfn(wrapper<T>(someT).value());
Run Code Online (Sandbox Code Playgroud)
再说一次:以这种方式完成是无能为力的,但更复杂的情况需要这个微不足道的工作.
从理论上讲,我们可以承认移开val从其临时包装给它的调用者,但是......什么签名应该有value()方法,这样势必时wrapper<T>是暂时的,但没有绑定时,它不是暂时的,为此value() const应首选?
在C++ 11中,您可以在方法上重载方法,否则this-pointer是一个右值:
T value() &&; //Will only be called if the object is a mutable rvalue
T value() const &; //Will only be called if the object is an lvalue
Run Code Online (Sandbox Code Playgroud)
请注意,根据 13.1.2 [over.load]标准,如果任何重载具有引用说明符(左值或右值),则必须得到一个.所以非临时案件的过载必须是const &.我不完全确定它是否会绑定到const r值,因此您可能需要const &&重载来捕获该情况.
我不知道编译器对此功能的支持,所以如果还没有支持,这可能在某种程度上是理论上的.在这种情况下,您可以通过创建move_value方法并使用调度到正确方法的自由函数来解决此问题:
template<class T> class wrapper {
...
T value() const;
T move_value();
};
template<typename T> T value(wrapper<T>&& self) { return std::move(self.move_value(); }
template<typename T> T value(const wrapper<T>& self) { return std::move(self.value(); }
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
168 次 |
| 最近记录: |