【问题标题】:Binary '[': no operator found which takes a left hand operand of type 'const SortableVector<int>'二进制“[”:未找到采用“const SortableVector<int>”类型的左手操作数的运算符
【发布时间】:2018-08-13 21:16:53
【问题描述】:

所以我在为我目前所在的课程编码时遇到了这个问题,我相信代码应该可以正常运行,但是出现了:二进制'[':没有找到采用左手操作数类型的运算符'常量排序向量' 我不太确定如何解决这个问题,有什么建议吗?

我最终查看了No '==' operator found which takes a left-hand operand of const Type,看看是否可以在那里找到解决方案,但我没有,看来我的问题源于我个人没有看到的东西。

#include <iostream>
#include "SortableVector.h"
using namespace std;

int main() {
    const int SIZE = 10;

    SortableVector<int> intTable(SIZE);

    for (int x = 0; x < SIZE; x++) {
        int z;
        cout << "Please enter a number with no decimals: ";
        cin >> z;
        intTable[x] = z;
    }

    cout << "These values are in intTable:\n";
    intTable.print();

    intTable.sortInt(intTable, SIZE);

    cout << "These values in intTable are now sorted: ";
    intTable.print();

    return 0;
}




//SortableVector.h
#include <iostream>
#include <cstdlib>
#include <memory>
#include <vector>
using namespace std;

struct IndexOutOfRangeException {
    const int index;
    IndexOutOfRangeException(int ix) : index(ix) {}
};
template<class T>
class SortableVector {
    unique_ptr<T[]> aptr;
    int vectorSize;
public:
    SortableVector(int);
    SortableVector(const SortableVector &);

    int size() const { return vectorSize; }
    T &operator[](int);
    void sortInt(SortableVector<int>, int);
    void print() const;
};

template<class T>
SortableVector<T>::SortableVector(int s) {
    vectorSize = s;
    aptr = make_unique<T[]>(s);
    for (int count = 0; count < vectorSize; count++) {
        aptr[count] = T();
    }
}

template<class T>
SortableVector<T>::SortableVector(const SortableVector &obj) {
    vectorSize = obj.vectorSize;
    aptr = make_unique<T[]>(obj.vectorSize);
    for (int count = 0; count < vectorSize; count++) {
        aptr[count] = obj[count];
    }
}

template<class T>
T &SortableVector<T>::operator[](int sub) {
    if (sub < 0 || sub >= vectorSize) {
        throw IndexOutOfRangeException(sub);
        return aptr[sub];
    }
}

template<class T>
void SortableVector<T>::sortInt(SortableVector<int> x, int z) {
    int i, j;
    int temp = 0;

    for (i = 0; i < z - 1; i++) {
        for (j = 0; j < z - 1; j++) {
            if (x[j] > x[j + 1]) {
                temp = x[j];
                x[j] = x[j + 1];
                x[j + 1] = temp;
            }
        }
    }
}

template<class T>
void SortableVector<T>::print() const {
    for (int k = 0; k < vectorSize; k++) {
        cout << aptr[k] << " ";
    }
    cout << endl;
}

【问题讨论】:

  • 您需要为您的班级提供const 版本的operator[] 函数。
  • 不相关,您现有的 operator[] 无法返回它声称的引用。有一条不归路。我相信你打算把 return aptr[sub]; 放在 if-block 之外。

标签: c++ arrays class templates bubble-sort


【解决方案1】:

您的operator[] 返回对元素的引用,这将允许人们直接更改元素。当您尝试在 const 对象上使用运算符时会出现问题(当您使用 const 引用将事物传递给函数时)。这将允许某人通过 operator[] 返回的引用更改对象,这会破坏 const 正确性,因此是不允许的。

如果您感到困惑,假设您有这样的课程:

class Foo
{
private:
    int numbers[100];
public:
    int& operator[](const int & pos)
    {
        return numbers[pos];
    }
};

这适用于创建对象和使用方括号运算符来访问元素。但是,当您尝试创建 const 对象时:

const Foo f;

你可以这样做:

f[3] = 5;

operator[]返回一个引用,可以用来直接改变f中存储的数据。 f 被声明为 const,所以这不能发生,编译器会报错。

解决方案是有两个版本的operator[],被它们的常量重载:

class Foo
{
private:
    int numbers[100];
public:
    int& operator[](const int &pos)
    {
        return const_cast<int&>(static_cast<const Foo&>(*this)[pos]);
    }
    const int& operator[](const int &pos) const
    {
        return numbers[pos];
    }
};

这里,非const版本实际上调用了const版本,以避免代码重复。

【讨论】:

  • 我个人不会担心numbers[pos];的重复
  • @DanielO'Grady 如果这有帮助,请通过单击此答案左侧的赞成/反对箭头下方的复选标记的轮廓来接受此答案。它将此问题标记为已回答。
猜你喜欢
  • 1970-01-01
  • 2019-07-31
  • 2013-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-17
  • 1970-01-01
  • 2018-01-26
相关资源
最近更新 更多