【问题标题】:How to check which type of subscript operator is called, lvalue or rvalue? [duplicate]如何检查调用了哪种类型的下标运算符,左值还是右值? [复制]
【发布时间】:2019-08-06 04:55:31
【问题描述】:

我写了一个 Vector 包装类。我想为这个类重载下标运算符。

如果用户想将一个值设置为大于大小的索引。我将向量大小调整为 index*2。

但是如果用户想从一个大于大小的索引中获取一个值。我会抛出一个异常。

那么,如何在重载的操作符方法中检查这两种情况呢?

矢量.h:

#include <iostream>
#include <vector>

using namespace std;

template <class T>
class Vector {
  vector<T> v;
  public:
    T& operator[] (const int index);
    T getmax ();
    int add (T val);
    int size();
    int capacity();
};

矢量.cpp

#include "Vector.h"


template <class T>
T Vector<T>::getmax (){
  T retval;
  return retval;
}


template <class T>
T& Vector<T>::operator[] (const int index){
    //How to check that which is called =>  v[5]=10(setting) or cout<<v[5]/getting)?
    if(index>v.size()-1){  
        v.resize(index*2); 
        return v[index];
    }
    else{
        return v[index];
    }
}


template <class T>
int Vector<T>::add (T val){ //return index
    v.push_back(val);
}


template <class T>
int Vector<T>::size (){
    return v.size();
}

template <class T>
int Vector<T>::capacity (){
    return v.capacity();
}

main.cpp

#include "Vector.cpp"
#include <iostream>


int main () {
  Vector<int> myobject;

  myobject.add(67);
  myobject[2]=99;

  cout <<"myobject[0]:"<<myobject[0]<<endl;
  cout <<"myobject[1]:"<<myobject[1]<<endl;
  cout <<"myobject[2]:"<<myobject[2]<<endl;
  cout <<"myobject[3]:"<<myobject[3]<<endl;

  return 0;
}

【问题讨论】:

  • 你不能。运算符不知道调用它的表达式。
  • 这简直是糟糕的设计。您可以解决一些问题,但不要这样做。

标签: c++ operator-overloading stdvector


【解决方案1】:

operator[] 无法知道用户是打算获取还是设置。但是,有一种解决方法。您可以让您的operator[] 返回某种类型,我们称之为VectorSubscriptResult&lt;T&gt;,它包含对向量和请求的索引的引用。这种类型VectorSubscriptResult&lt;T&gt; 将有一个operator T&amp;,如果有人想要获取该值,将调用它,以及一个operator=,如果有人想要设置它,将调用它。 (我将把它作为练习留给读者如何处理operator[]() const 的情况。)

【讨论】:

  • 但是vector&lt;bool&gt; 是这样工作的,我想几乎每个人都同意这是不好的
  • @LightnessRacesinOrbit 我认为大部分的坏处来自于矢量 与带有 T != bool 的矢量 的工作方式不同。对我来说,否则会那么糟糕。
  • 也许,但通过扩展,人们确实希望 operator[] 通常也能以某种方式工作
  • @LightnessRacesinOrbit 让operator[] 返回代理对象没有任何问题。如果您想获取索引元素的地址,您可能需要添加的唯一其他内容是operator&amp;
【解决方案2】:

您可以为const 和非const 对象重载operator []

T& operator[] (const int index);
T const& operator[] (const int index) const;

但是,如果您有一个非const 对象,即使您的意图是get 而不是set,也会调用第一个重载。如果你想在 getset 之间实现不同的行为,最好有两个这样的函数。

T const& get(int index) const;
void set(int index, T const&);

【讨论】:

    猜你喜欢
    • 2014-03-17
    • 2021-09-26
    • 1970-01-01
    • 2011-04-20
    • 2019-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-10
    相关资源
    最近更新 更多