Peter Trade
Peter Trade

Reputation: 21

overload assignment and round bracket operator in C++

I want to define a class myVector that support both assignment operator= and bracket access e.g myclass(1) = 0.5. See a dummy example below

class myVector
{
public:
    vector<double> _v;
    myVector(unsigned int size) : _v(size, 0) { }

    double& operator()(int i)
    {
        return _v[i];
    }

    unsigned int size() const { return _v.size(); }

    myVector& operator=(const myVector& v)
    {
        _v.resize(v.size());
        for(int i=0;i<v.size();i++)
            _v[i] = v(i);
    }
}

This code cannot be compiled since () is not defined as a constant function. This is because I want to enable direct assignment such as myvector(1) = 2. To solve this problem, I can only think of two solutions. One is to define sth. like double getValue(int i) const but this seems weird since some duplicate code is added. The other is to remove const from the signature of () function, but that is undesirable as well. I am sure there will be a good work around but I cannot find it.

Upvotes: 2

Views: 5780

Answers (2)

For the particular case of the operator(), you should just provide two overloads:

double& operator()( int i ) { return _v[i]; }
double operator()( int i ) const { return _v[i]; } // [1]

If this was a templated container, the second overload would return a const&, but given that it is a double, returning a copy is fine.

Now as a recommendation, you can implement the copy constructor, and then implement a simple swap function:

void myVector::swap( myVector & lhs ) {
   _v.swap( lhs._v );
}

With those two tools in place, then you can use the idiomatic implementation of operator=:

myVector& myVector::operator=( myVector rhs ) { // by value
   swap( *this, rhs );
   return *this;
}

The other thing is that it does not make sense to roll your own loop to copy the vectors, they already know how to do that by themselves, so _v = v._v; has the same effect as your loop.

Upvotes: 0

Ben Voigt
Ben Voigt

Reputation: 283624

The correct solution is "both". Member functions, including operators, can be overloaded on const-ness (the this pointer is effectively a parameter and takes part in overload resolution).

double& operator()(int i) { return _v[i]; }
double operator()(int i) const { return _v[i]; }

NOTE: With non-member operators, the left-hand object isn't just like a parameter, it IS a parameter.

Upvotes: 2

Related Questions