C++ 检测向量的[]运算符是否用于RHS或LHS

C++ 检测向量的[]运算符是否用于RHS或LHS,c++,vector,C++,Vector,假设以下是vector的[]运算符实现: template<class T> T& Vector<T>::operator[](unsigned int index) { if(index >= my_capacity) { if(1 /*something to check that [] operator was used in RHS (means read)*/) cout << "Out of boun

假设以下是vector的[]运算符实现:

template<class T>
T& Vector<T>::operator[](unsigned int index)
{
    if(index >= my_capacity) {
        if(1 /*something to check that [] operator was used in RHS (means read)*/) cout << "Out of bounds read" << endl;
        else cout << "Out of bounds write" << endl; //means write operation
    }
    return arr[index];
}
我基本上希望得到如下输出:

Out of bounds read
Out of bounds write
我应该如何确定“if”中的条件(对[]运算符的调用是读还是写)?有人能帮我吗?非常感谢

你不能

解决方法不是返回引用,而是返回一个代理对象,该代理对象可以检测它是从中读取还是写入。但是因为C++没有允许(重载<代码>操作符.<代码>),这样的代理永远不能完全透明。 我的经验告诉我这不值得。

你不值得

解决方法不是返回引用,而是返回一个代理对象,该代理对象可以检测它是从中读取还是写入。但是因为C++没有允许(重载<代码>操作符.<代码>),这样的代理永远不能完全透明。
根据我的经验,这是不值得的。

唯一的方法是让
操作符[]
返回一个代理对象,该对象实现单独的转换(读取)和赋值(写入)操作符,例如:

模板
结构向量代理
{
向量&vec;
无符号整数索引;
算子T&(){
如果(索引>=向量我的容量){
抛出std::runtime_错误(“越界读取”);
返回向量arr[索引];
}
向量代理和运算符=(常量T和val){
如果(索引>=向量我的容量){
抛出std::runtime_错误(“越界写入”);
向量arr[index]=val;
归还*这个;
}
};
样板
VectorProxy向量::运算符[](无符号整数索引)
{
返回向量proxy{*this,index};
}
/*可选:
样板
结构向量constproxy
{
常数向量&vec;
常量无符号整数索引;
运算符常量T&()常量{
如果(索引>=向量我的容量){
抛出std::runtime_错误(“越界读取”);
返回向量arr[索引];
}
};
样板
VectorConstProxy Vector::运算符[](无符号整数索引)常量
{
返回VectorConstProxy{*this,index};
}
*/
intmain()
{
...
向量v(5,10);
试一试{
int ans=v[10];
}
捕获(const std::exception&e){

cout执行所需操作的唯一方法是让
操作符[]
返回一个代理对象,该对象实现单独的转换(读取)和赋值(写入)操作符,例如:

模板
结构向量代理
{
向量&vec;
无符号整数索引;
算子T&(){
如果(索引>=向量我的容量){
抛出std::runtime_错误(“越界读取”);
返回向量arr[索引];
}
向量代理和运算符=(常量T和val){
如果(索引>=向量我的容量){
抛出std::runtime_错误(“越界写入”);
向量arr[index]=val;
归还*这个;
}
};
样板
VectorProxy向量::运算符[](无符号整数索引)
{
返回向量proxy{*this,index};
}
/*可选:
样板
结构向量constproxy
{
常数向量&vec;
常量无符号整数索引;
运算符常量T&()常量{
如果(索引>=向量我的容量){
抛出std::runtime_错误(“越界读取”);
返回向量arr[索引];
}
};
样板
VectorConstProxy Vector::运算符[](无符号整数索引)常量
{
返回VectorConstProxy{*this,index};
}
*/
intmain()
{
...
向量v(5,10);
试一试{
int ans=v[10];
}
捕获(const std::exception&e){
不能用另一种方法

  • 定义两个helper
    struct
    s——一个用于读取,另一个用于写入

  • 使用这些类型重载
    运算符[]

  • 更新调用以使用适当的辅助对象

  • 另一种方法

  • 定义两个helper
    struct
    s——一个用于读取,另一个用于写入

  • 使用这些类型重载
    运算符[]

  • 更新调用以使用适当的辅助对象



  • 我认为如果没有呼叫的附加信息,您无法区分第一个和第二个。@RSahu我也有同样的感觉,但我可以发送什么附加参数?您这样做只是为了更好地记录吗?@HolyBlackCat抱歉,我不明白。如果没有附加信息,我认为您无法区分第一个和第二个调用。@RSahu我也有同样的感觉,但是我可以发送什么额外的参数?你这样做只是为了更好地记录吗?@HolyBlackCat抱歉我不理解,非常感谢!非常感谢!非常感谢!非常感谢!非常感谢!非常感谢!那么,使用名为
    GetRead
    GetWrite
    的两个方法怎么样?这很好如果您可以自由支配类的使用方式,那么这是一种更简单的方法。@AyxanHaqverdili,这可能是个人的爱好,但我喜欢基于类型重载,而不是使用不同名称的函数。非常感谢!那么,只使用两个名为
    GetRead
    GetWrite
    的方法如何?如果您有fre控制类的使用方式。@AyxanHaqverdili,这可能是个人喜好,但我喜欢基于类型重载,而不是使用不同名称的函数。
    int ans = v[10]; //First
    v[10] = 1; //Second
    
    Out of bounds read
    Out of bounds write
    
    struct ReadIndex { unsigned int index = 0;};
    struct WriteIndex { unsigned int index = 0;};
    
    template<class T>
    T const& Vector<T>::operator[](ReadIndex r) const
    {
        if(r.index >= my_capacity) {
            cout << "Out of bounds for read" << endl;
        }
        return arr[r.index];
    }
    
    template<class T>
    T& Vector<T>::operator[](WriteIndex w)
    {
        if(w.index >= my_capacity) {
            cout << "Out of bounds for write" << endl;
        }
        return arr[w.index];
    }
    
    int ans = v[ReadIndex{10}];
    v[WriteIndex{10}] = 1;