3

コピーと移動の両方をサポートする必要がある別のパラメトリック クラスを埋め込むクラスがあるとします。そして、特定の状況で、何らかの方法で内部値を取得する必要があると仮定しましょう。

典型的なアプローチは次のとおりです。

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;
};

それを行う唯一の方法ではありません。コピーと移動を説明する必要はないかもしれませんが、そのままにしておいてください。

要点は別です。特定のインスタンスでは、それ自体が copy/movable class であるとしますT。もちろん、wrapper::value()T のコピーを返します。

ここで、返された T をパラメーターとして別の呼び出しに渡す必要があり、含まれているラッパーが一時的なものであるとします。

より簡単なシミュレーションは、

calledfn(wrapper<T>(someT).value());

繰り返しますが、この方法で行うのは無知ですが、より複雑なケースでは、この些細なケースが機能する必要があります。

理論的には、一時的なラッパーから離れて呼び出し元に渡すことを認めることができますが、一時的な場合はバインドされ、一時的でない場合はバインドされないようvalに、どの署名にvalue()メソッドが必要ですか。優先されますか?wrapper<T>value() const

4

1 に答える 1

6

thisC ++ 11では、 -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

標準によると 13.1.2 [over.load]、オーバーロードに参照指定子(左辺値または右辺値)がある場合は、すべて1つを取得する必要があることに注意してください。したがって、非一時的な場合の過負荷はである必要がありますconst &。これがconstr-valueにバインドされるかどうかは完全にはわかりません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(); }
于 2012-06-28T13:04:41.403 に答える