c++classoperator-overloadingsquare-bracket

C++ operator overloading [] and return types


I'm just revisiting C++, and I have a question about overloading of the [] operator, and more specifically why my program doesn't work.

Given the following code in vec.cpp:

double Vec::operator[](unsigned int i) const {
    return this->values[i];
}

double & Vec::operator[](unsigned int i) {
    return this->values[i];
}

These are defined in vec.h as methods to the Vec class, and if I do not use the operator in my main.cpp, all is fine and dandy. It compiles just as normal with no errors.

However once I do this in my main function (which is using std::cout and std::endl):

cout << a[0] << endl;

Things go wrong. The errors I get are a bunch of

candidate function template not viable: no known conversion from 'Vec' to 'char' for 2nd argument
operator<<(basic_ostream<_CharT, _Traits>& __os, char __cn)

where you can replace 'char' with any primitive data type.

Here is a working example

// In vec.h
#pragma once

#include <string>
#include <iostream>

class Vec {
    private:
        int dims;
        double *values;
    public:
        Vec(int dims, double values[]);
        double operator [](unsigned int i) const;
        double& operator[](unsigned int i);
};
// In vec.cpp
#include <iostream>
#include <string>
#include <cmath>

#include "vec.h"

using std::cerr, std::endl, std::cout;

Vec::Vec(int dims, double values[]) {
    this->dims = dims;
    this->values = new double[dims];
    for(int i = 0; i < dims; i++) {
        this->values[i] = values[i];
    }
}

double Vec::operator[](unsigned int i) const {
    if(i >= this->dims) {
        cerr << "Elem out of range" << endl;
    }
    return this->values[i];
}

double & Vec::operator[](unsigned int i) {
    if(i >= this->dims) {
        cerr << "Elem out of range" << endl;
    }
    return this->values[i];
}
// In main.cpp
#include <iostream>
#include <string>

#include "vec.h"

using std::cout, std::endl;

int main() {
    double avals[2];
    avals[0] = 1.0;
    avals[1] = 2.0;
    Vec *a = new Vec(2, avals);

    cout << a[0] << endl; // Error occurs here

    return 0;
}

Can anyone help me sort this out?


Solution

  • In this declaration

    Vec *a = new Vec(2, avals);
    

    there is declared a pointer of the type Vec *. So an expression with the dereferenced pointer has the type Vec.

    So in this statement

    cout << a[0] << endl;
    

    the expression a[0] has the type Vec.

    It seems you mean

    ( *a )[0]
    

    or

    a[0][0]