1

しばらくの間、頭を悩ませていることがあります。戻り値の型に基づいて [] 演算子をオーバーロードしようとしています。これが私がする必要があることです:

class A {

private:
    double* data_;
    int N_;
public:
    A (N=0):N_(N){
        data_ = new double[N];
    }
    ~A {delete[] data_;}

    double operator[] (const int i) {
        return data_[i];
    }

    double* operator[] (const int i) {
        return &data[i]; // for example; in fact here i need to return some block of data_ 
    }
};

このコードはコンパイルされません。それが私の問題です。誰かがこの問題を解決するのを手伝ってくれますか?

PS:たとえば、戻り値の型で通常の関数をオーバーロードする方法を知っています:

int foo ();
string foo ();

このフォーラムで読んだいくつかのトリックを使用しました。この上:

struct func {
    operator string() { return "1";}
    operator int() { return 2; }
};

int main( ) {
    int x    = func(); // calls int version
    string y = func(); // calls string version
    double d = func(); // calls int version
    cout << func() << endl; // calls int version
    func(); // calls neither
}

ありがとうございました。

4

3 に答える 3

14

2 つのメソッド オーバーロードには、異なる署名が必要です。戻り値の型は、メソッドのシグネチャの一部ではありません。

于 2012-05-30T21:33:39.313 に答える
4

関数に使用するのと同じ「トリック」を使用できます。つまり、変換演算子でプロキシ オブジェクトを使用します。

class A
{
  private:
    double* data_;
    int N_;
  public:
    A (int N = 0)
      : N_(N), data_(new double[N])
    {}
    ~A() { delete[] data_; }

    struct proxy
    {
        int i;
        double * data;
        operator double() const
        {
            return data[i];
        }

        operator double*()
        {
            return &data[i];
        }

        operator double const *() const
        {
            return &data[i];
        }
    };

    proxy operator[] (int const i) {
        proxy p { i, data_ };        
        return p;
    }

    proxy const operator[] (int const i) const {
        proxy p { i, data_ };        
        return p;
    }
};

int main()
{
  {
    A a(12);

    double d = a[0];
    double * pd = a[0];
  }

  {
    A const ca(12);

    double d = ca[0];
    //double * pd = ca[0]; // does not compile thanks to overloads on const
    double const * pcd = ca[0];
  }
}

しかし、これはひどい考えだと私は主張します。operator[]値またはこの値へのポインターを返すと、クラスのユーザーを混乱させることが保証されています。また、両方の型が可能な式で使用することは実用的ではありません。たとえば、std::cout << a[0];コンパイルされません (あいまいなオーバーロード)。

于 2012-06-19T08:48:06.270 に答える
0

おそらく、次のようなものが必要です。

class A {

private:
    double* data_;
    int N_;
    ... // other stuff
public:
    double operator[] (const int i) const { // note const here
        return data_[i];
    }

    double& operator[] (const int i) { // note reference here
        return data_[i];
    }
};

また、意味を持たせるには、オペレーターを公開する必要があります。

于 2012-05-30T21:47:17.987 に答える