16

最近、次の例に示すように、C++ での式への代入についての議論に従いました。

string s1, s2, s3;
(s1 + s2) = s3;

C++11 では、代入演算子を左辺値参照 (左側) に制限することができます。次のように代入演算子を宣言すると、型に互換性がないため、コンパイラ Clang はエラー メッセージを表示してコードを拒否します。

auto operator=(const string& rhs) & -> string&;
auto operator=(string&& rhs) & -> string&;

私はこれをどこにも見たことがありません。代入演算子に左辺値参照修飾子を使用しない正当な理由はありますか (ほとんどのコンパイラでサポートされていないことに加えて)?

4

3 に答える 3

8

面白い!私はこれに気づいていなかったので、見つけるのに時間がかかりました (これは「移動セマンティクスを *this に拡張する」提案の一部でした)。表記法は、誰かが見たい場合に備えて、8.3.5 [dcl.decl] パラグラフ 4 で定義されています。

とにかく、この機能について知っていると、関数が呼び出されるオブジェクトが左辺値または右辺値である場合、オーバーロードに使用し、おそらく異なる動作をするのに最も役立つようです。特にオブジェクトが実際に左辺値である場合は、代入の結果など、実行できることを制限するためにそれを使用する必要はないようです。たとえば、右辺値への割り当てから右辺値を返す構文が必要な場合があります。

struct T {
    auto operator=(T&) & -> T&;
    auto operator=(T&&) & -> T&;
    auto operator=(T&) && -> T;
    auto operator=(T&&) && -> T;
};

ここでの意図は、割り当ての結果から移動できるようにすることです (それが価値があるかどうかはわかりませんが、そもそも割り当てをスキップしてみませんか?)。この機能を主に用途を制限するために使用するとは思いません。

個人的には、右辺値から左辺値を取得できる可能性があり、代入演算子は多くの場合これを行う方法です。たとえば、左辺値を関数に渡す必要があるが、それで何も使用したくないことがわかっている場合は、代入演算子を使用して左辺値を取得できます。

#include <vector>
void f(std::vector<int>&);
int main()
{
    f(std::vector<int>() = std::vector<int>(10));
}

これは、右辺値から左辺値を取得するための代入演算子の悪用である可能性がありますが、偶然に発生する可能性は低いです。したがって、代入演算子を左辺値のみに適用できるように制限することで、無理をしてこれを不可能にするつもりはありません。もちろん、割り当てから右辺値への右辺値を返すこともこれを防ぎます。2 つの使用法のうち、どちらがより有用であるかは、検討の対象になる可能性があります。

ところで、clang は、バージョン 2.9 以降で引用した構文をサポートしているようです。

于 2012-10-06T12:50:26.310 に答える
4

代入演算子に左辺値参照修飾子を使用しない正当な理由はありますか (ほとんどのコンパイラでサポートされていないことに加えて)?

いいえ、そうではありません。左辺値または右辺値オブジェクトの正しいインターフェイスを構築するために左辺値または右辺値修飾子を使用することは、 を使用するconstこととまったく同じであり、同じ方法でアプローチする必要があります。各関数は制限のために考慮する必要があります。右辺値への代入は実際には意味がないため、禁止する必要があります。

あなたがそれを見たことがない理由は、ほとんどが貧弱なコンパイラサポートです-右辺値参照*thisはちょっと似thread_localています.ほとんどのコンパイラ実装者は、「C++ 11から実装する機能」スタックの一番下近くにそれを置いたようです.

于 2012-10-06T12:54:56.413 に答える
4

私があなたの提案にそれほど熱心ではない理由の 1 つは、特別なメンバーを宣言することを完全に避けようとしているからです。したがって、私の代入演算子のほとんどは暗黙的に宣言されているため、参照修飾子はありません。

もちろん、たとえば所有権を管理するためにクラスまたはクラス テンプレートを作成する場合 (上記のリンクの結論を参照)、左辺値のみに対してこれらの演算子を宣言するように注意することができます。ただし、クライアントには影響がないため、あまり意味がありません。

于 2012-10-06T14:11:16.767 に答える