没有“右值引用*此”功能的解决方法


67

我在可移动对象周围有一个代理容器类,并希望该代理能够隐式地产生对基础对象的右值引用,但仅当代理自身被移动时才是如此。

我相信我将能够按照建议n2439 “将移动语义扩展到* this”来实现此行为,但是它在gcc发行版中尚不可用,并且将有一段时间。

下面的代码是我最终的目标,但是目前无法实现。在我可以使用此功能之前,是否有任何等效的解决方法?

template< class T >
struct movable_proxy {
    operator T&&() && {
        return std::move(value);
    }

    operator const T&() const& {
        return value;
    }

private:
    T value;
};

9
我认为您将获得的最接近的函数是一个显式执行转换的函数,而不是具有转换运算符,因此您必须说convert_proxy(p)哪个重载了rvalues和lvalues以返回T&&or或const T&...,但这使代理的使用不透明,这可能不是您想要的
Jonathan Wakely 2013年

5
我很好奇。抱歉,缺乏理解,但我想知道。如果删除新提议的&&&修饰符,则您到底缺少什么?
安迪·普罗



14
@无所不能,只是因为它尚未实现。这是缺少的最后一个核心语言功能,但是对它的需求(或恕我直言的需求)比lambda,右值引用等少得多。它将出现在GCC 4.9中,对于某些人甚至可能是4.8.xx > 0
Jonathan Wakely

Answers:


4

好问题。我最近尝试编写类似的代理类,但从未获得好的解决方案。我发现最好的方法是在每次需要将代理作为r值的用途上调用成员函数:

ORef<T> move() {
    return ORef<T>( this->release() );
}

这改变声明的东西从R值的语义std::move(proxy)proxy.move(),但也允许返回不同类型的(隐式转换为你需要的类型)的对象的可能性。

我使用此代码的编码做法是始终将代理对象作为右值传递,从而强制手动指定语义(移动,共享引用,复制等),但是这当然会使使用错误成为潜在的问题(例如x.move(),在最终使用之前调用x) 。


谢谢@dhardy; 我最终得到了一个完全相同的代理类型,并带有一个“发布”呼叫以及您提到的相同使用错误。可惜似乎没有一种解决方法,但是我想这确实使必要的语言扩展成为了一个很好的选择。
boycy
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.