【问题标题】:Why array indexing not showing commutative behavior in this program?为什么数组索引在这个程序中没有显示交换行为?
【发布时间】:2015-05-30 14:47:15
【问题描述】:

我知道数组索引在 C 和 C++ 中都是可交换的,所以 a[i] 与 i[a] 相同,它的效果与 i[a] 相同,并且两者都是有效的。但是最近我写了一个下面的程序,当我使用 i[intob] 而不是 tob[i] 时编译失败。

#include <iostream>
#include <cstdlib>
using std::cout;
template<class T>class atype
{
    T* a;
    int size;
    public:
        atype(int n)
        {
            size=n;
            a=new T[size];
            for(auto i=0;i<size;i++)
                a[i]=i;
        }
        ~atype()
        {
            delete[] a;
        }
        T& operator[](int i);
};
template<class T> T& atype<T>::operator[](int i)
{
    if(i<0 || i>size)
    {
        cout<<"\nIndex value of ";
        cout<<i<<" is out of bounds.\n";
        exit(1);
    }
    return a[i];   // i[a] also works fine here.
}
int main()
{
    int i,n;
    cout<<"Enter value of n: ";
    std::cin>>n;
    atype<int> intob{n};
    atype<long int> longintob{n};
    cout<<"Integer array: ";
    for(i=0;i<n;i++)
        intob[i]=i; 
    for(i=0;i<n;i++)
        cout<<i[intob]<<' ';    // oops compiler error why???
    cout<<'\n';

    cout<<"long integer array: ";
    for(i=0;i<n;i++)
        longintob[i]=i;
    for(i=0;i<n;i++)
        cout<<longintob[i]<<' ';
    longintob[15]=123;
}

我收到以下编译器错误。

[错误] 'operator[]' 不匹配(操作数类型为 'int' 和 'atype')

但是,如果我在重载的 [] 运算符函数中编写 i[a],那么它可以正常工作。为什么?

是否存在使用 i[intob] 访问数组元素的解决方案?

如果我在某处错了或理解有误,请告诉我。

【问题讨论】:

  • atype 违反了三原则。
  • 你有一个析构函数,但没有复制构造函数和复制赋值运算符。
  • 如果你写atype&lt;int&gt; a(1), b(1); a = b;你有内存泄漏和双重释放。
  • @fredoverflow:但我没有执行任何任务或复制。那为什么我需要写赋值运算符和复制构造函数呢?如果我真的不需要作业或副本怎么办。
  • 然后你应该将复制构造函数和赋值运算符声明为私有,并让它们未实现。或者 = delete 他们,如果你有 C++11 编译器。

标签: c++ arrays templates compiler-errors


【解决方案1】:

索引运算符本身不可交换。

如果您了解对于数组(或指针)a 和索引 ia[i] 等效于 *(a + i) 会有所帮助。交换位来自那个加法,因为*(a + i) 等于*(i + a),这导致i[a] 有效。

【讨论】:

    【解决方案2】:

    因为编译器会检查类型,而在 c++ 中有一种叫做 运算符重载 的东西,这意味着我可以为自己的类型编写自己的运算符:

    typedef int stupidInt;
    
    intoperator+(int l, stupidInt r){
      return l-r;
    }
    
    int operator+(stupidInt l, int r){
      return l+r;
    }
    stupidInt a = 3;
    int b = 7;
    
    a + b == 10; 
    b + a == 4; 
    

    这也适用于 operator[](typea, typeb);

    并且某处可能有一个定义 operator[](atype, int) 。 (也许这是在编译器中硬编码的) 但反之则不然。

    您也没有真正的理由需要反过来说。但你可能可以定义

    int operator[](int i, atype a){
      return a[i];
    }
    

    这应该使运算符也可以反向工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-16
      • 2011-08-20
      • 1970-01-01
      • 2021-04-04
      • 2018-05-17
      • 1970-01-01
      • 2015-08-02
      相关资源
      最近更新 更多