0

参照ではなく値を返すようにオーバーロードされた演算子を変更するにはどうすればよいですか?

#include <iostream>
using namespace std;

class IntList 
{ 
private: 
    int list[1]; 
public:
    IntList() {list[0] = 0;}
    int& operator[] (const int index) {return list[index];} 
}; 

int main()
{
    IntList list;

    cout << list[0] << endl;
    list[0] = 1;
    cout << list[0] << endl;
    return 0;
}
4

3 に答える 3

3
int operator[] (const int index){}
^^^^^

を取り除くだけ&です。これを行うと、配列要素に値を割り当てるために使用できなくなります。

参照を返す場合と参照しない場合の違い

お気づきのようにoperator []、参照を返すときに、割り当ての左側で使用できます。これが可能なのは、参照によって返す場合の戻り値が左辺値でoperator []あるためです。メモリに格納され、アドレスを持つ変数の参照を取得できるため、参照は左辺値として扱われます。値によって返される場合、式
は最終的に[#]を次のように 評価します。operator []list[0] = 1;

1=1;

は左辺値ではないため、これは非論理的1です。コンパイラは、左側のオペランドが左辺値でなければならないという診断を生成します。

[#] 添字 0 の要素の値が 1 であると仮定します

于 2013-06-29T18:14:20.213 に答える
0

コード例では、参照を返す必要がある代入を使用しています。

list[0] = 1;
list.operator[](0) = 1;
int& xref = list.operator[](0);
(xref) = 1; // <-- changed the value of list element 0.

operator[](int index) が値を返すようにしたい場合、これは次のように変換されます。

int x = list.operator[](0);
x = 1; <-- you changed x, not list[0].

operator[](int index) で値を返すだけでなく、list[0] = 1 も機能するようにする場合は、2 つのバージョンの演算子を提供して、コンパイラがどちらの動作を試みているかを判断できるようにする必要があります。特定の呼び出しで呼び出すには:

// const member, returns a value.
int operator[] (const int index) const {return list[index];} 

// non const member, which returns a reference to allow n[i] = x;
int& operator[] (const int index) {return list[index];} 

戻り値の型とメンバー定数の両方が異なる必要があることに注意してください。

#include <iostream>
using namespace std;

class IntList 
{ 
private: 
    int list[1]; 
public:
    IntList() {list[0] = 0;}
    int operator[] (const int index) const { return list[index]; }
    int& operator[] (const int index) {return list[index];} 
}; 

int main(int argc, const char** argv)
{
    IntList list;

    cout << list[0] << endl;
    list[0] = 1;
    int x = list[0];
    cout << list[0] << ", " << x << endl;
    return 0;
}

実際のデモ: http://ideone.com/9UEJND

于 2013-06-29T19:10:43.190 に答える