在返回类型上重载operator []

时间:2012-05-30 21:32:01

标签: c++

有一些事情让我的大脑陷入困境:我试图根据返回类型重载[]运算符。这是我需要做的:

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
}

谢谢。

3 个答案:

答案 0 :(得分:14)

两个方法重载必须具有不同的签名。返回类型不是方法签名的一部分。

答案 1 :(得分: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];不会编译(模糊的重载)。

答案 2 :(得分: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];
    }
};

运营商也应该公开有意义。