【问题标题】:overload operator[] on return type返回类型上的重载运算符 []
【发布时间】:2012-06-19 16:48:06
【问题描述】:

有一件事让我的大脑一直很困扰:我试图根据返回类型重载 [] 运算符。这是我需要做的:

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
}

谢谢。

【问题讨论】:

  • "PS:例如,我知道如何在返回类型上重载普通函数"你确定吗?
  • 你在说什么论坛?
  • 您能告诉我们如何仅在返回类型上重载吗?我想这里很多人也想知道,因为他们不知道......
  • 点击这个链接[link]stackoverflow.com/questions/442026/…
  • @user1427050 :该链接说它不能在 C++ 中完成。你在说什么?

标签: c++


【解决方案1】:

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

【讨论】:

  • +1; C++11 引用,第 1.3.20 节:“signature:名称、参数类型列表、函数所属的类、cv-限定符(如果有)和 ref 限定符(如果有)"
【解决方案2】:

您可以使用与函数相同的“技巧”,即使用带有转换运算符的代理对象:

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 &lt;&lt; a[0]; 不会编译(不明确的重载)。

【讨论】:

  • 不错的努力,但 +1 提到它是一个可怕的想法。
  • 谢谢!最后我决定创建另一个成员函数来重载 'operator[]'
【解决方案3】:

可能你需要这样的东西:

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];
    }
};

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

【讨论】:

  • 实际上我需要的是返回一个集合 {data_[i], data_[i+1]} of 2 double(这可以通过使用一些 SSE 内在函数来实现)...
  • 请注意,在您像我写的那样定义运算符后,您可以像这样使用它:'&object[i]',您将获得其他处理所需的地址/指针。
猜你喜欢
  • 2015-01-29
  • 1970-01-01
  • 2015-04-26
  • 1970-01-01
  • 1970-01-01
  • 2015-06-03
  • 1970-01-01
  • 2012-04-26
  • 1970-01-01
相关资源
最近更新 更多