3

constバージョンでoperator()をオーバーロードするのに問題があります:

#include <iostream>
#include <vector>
using namespace std;

class Matrix {
public:
    Matrix(int m, int n) { 
        vector<double> tmp(m, 0.0);
        data.resize(n, tmp);
    }
    ~Matrix() { }


    const double & operator()(int ii, int jj) const {
        cout << " - const-version was called - ";
        return data[ii][jj];
    }

    double & operator()(int ii, int jj) {
        cout << " - NONconst-version was called - ";
        if (ii!=1) {
            throw "Error: you may only alter the first row of the matrix.";
        }
        return data[ii][jj];
     }


protected:  
    vector< vector<double> > data;
};

int main() {
try {
    Matrix A(10,10);
    A(1,1) = 8.8;
    cout << "A(1,1)=" << A(1,1) << endl;
    cout << "A(2,2)=" << A(2,2) << endl;
    double tmp = A(3,3);
} catch (const char* c) { cout << c << endl; }
}

これにより、次の出力が得られます。

  • NONconst-versionが呼び出されました---NONconst-versionが呼び出されました-A(1,1)= 8.8
  • NONconst-バージョンが呼び出されました-エラー:マトリックスの最初の行のみを変更できます。

C ++がoperator()のconst-versionを呼び出すようにするにはどうすればよいですか?GCC4.4.0を使用しています。

4

5 に答える 5

3

オーバーロードは問題ないように見えますが、constオブジェクトで呼び出すことはありません。あなたはこれを試すことができます:

void foo(const Matrix& A) {
  cout << "A(1,1)=" << A(1,1) << endl;
}

Matrix A(10,10);
foo(A);

これはあなたに与えます:

 - const-version was called - A(1,1)=0
于 2010-03-14T00:40:08.813 に答える
2

メソッドを呼び出すオブジェクトは const でなければなりません。

cout << "A(2,2)=" << (*static_cast<const Matrix*>(&A))(2,2) << endl;
于 2010-03-14T00:32:48.337 に答える
1

通常、戻り値の処理に応じて、関数のconstバージョンまたはnon-constバージョンを呼び出すことはできません。同様の機能をエミュレートしたい場合は、プロキシを返してみて、それを使って何をするかに応じて動作を切り替えてみてください。

class Proxy
{
  Matrix& m;
  int x, y;
public:
  ...
// mutating operations
  operator double&() { check(); return m.index(x,y); }
  double& operator=(double d) { check(); return m.index(x,y)=d; }
// ... other mutating operations (+=, ...) analogously

// nonmutating ops
  operator double() { return m.const_index(x, y); }
  operator const double&() // ... same
};

Proxy Matrix::operator(int x, int y)
{
  return Proxy(*this, x, y);
}

check()は、法的な突然変異(に統合される可能性がありますindex())のチェックでindex()ありconst_index()、特定の場所への参照または定数参照を提供するMatrixのメソッドであると想定しています。

于 2010-03-14T00:54:37.217 に答える
0

const_cast<>() を使用するか、インスタンスを const にします。

演算子が const double を返すことを確認したいのではないでしょうか? たぶん、他のバージョンではなく、const バージョンを提供する必要があります。

于 2010-03-14T00:29:01.363 に答える
0

機能が異なるさまざまなメソッドがあるため、それらに異なる名前を付けます。const次に、必要なものを呼び出すためだけにオブジェクトを用意する必要はありません。

constオブジェクトがあるoperator() const場合に備えて、代替関数を呼び出すことができます。ただし、代替機能は、わかりやすい名前の関数に入れる必要があります。

constオブジェクトへのハンドルを取得するには、 を使用しますstatic_cast< const Matrix & >( A )

于 2010-03-14T03:45:13.453 に答える