views:

368

answers:

6

Where, ClassA has an operator as such, that returns ClassB:

class ClassA
{
public:
    ClassA();
    ClassB &operator[](int index);
}

If I want to access said operator from within ClassA's constructor, as so:

ClassA::ClassA()
{
    // How do I access the [] operator?
}

At the moment, as a work-around I'm just using a method called GetAtIndex(int index) which the [] operator calls, and so does the constructor.

It would be nice if I could access it in the same as as C# works:

// Note: This is C#
class ClassA
{
   ClassB this[int index]
   {
       get { /* ... */ }
       set { /* ... */ }
   }

   void ClassA()
   {
       this[0] = new ClassB();
   }
}

Note: I'm using g++

A: 
 ClassA::ClassA()
 {
     this->operator[]( someindex ) = whatever;
 }

But make sure that whatever member data the operator may depend on is fully constructed before you use it.

anon
+7  A: 

Try the following

(*this)[0] = ...
JaredPar
Spot on, thanks! :)
nbolton
+9  A: 

You can use:

this->operator[](0) = ...

or:

(*this)[0] = ...

But the syntax is a little awkward. I usually make another method called get and use that, e.g.:

ClassB& get(size_t index) {
    return this->operator[](0); // or something more direct
}

Then when you want to use it you can just say:

this->get(0) = ...
tgamblin
A: 

Here's another way, not sure if it's useful...

ClassA::ClassA()
{
    ClassA &_this = *this;
    _this[0] = someValue;
    _this[1] = someValue;
    _this[2] = someValue;
    _this[3] = someValue;
    _this[4] = someValue;
}
nbolton
The third line should be "ClassA" so you aren't making a copy of this.
Matthew Crumley
Yea, this code is wrong.
GMan
Oops :) - This code is now fixed.
nbolton
+3  A: 

Another solution is to follow the STL style by making an "at" function:

const ClassB& at(int index) const
{
    return /* get it by index */;
}

ClassB& at(int index)
{
    return /* get it by index */;
}

const ClassB& operator[](unsigned index) const
{
    return at(index);
}

ClassB& operator[](unsigned index)
{
    return at(index);
}

But usually "at" does range checks (and possibly throws std::out_of_range) while [] does not, so you might make a private function (const and non-const) to factor both out:

public:
    const ClassB& at(int index) const
    {
        if ( /* out of range */ )
        {
            throw std::out_of_range( /* message */ );
        }

        return get(index);
    }

    ClassB& at(int index)
    {
        if ( /* out of range */ )
        {
            throw std::out_of_range( /* message */ );
        }

        return get(index);
    }

    const ClassB& operator[](unsigned index) const
    {
        return get(index);
    }

    ClassB& operator[](unsigned index)
    {
        return get(index);
    }

private:
    const ClassB& get(int index) const { return /* get it by index */; }
    ClassB& get(int index) { return /* get it by index */; }

Now you only have to maintain your get functions. Now you can call "get" in your constructor, or at, or (*this)[].

But doing "at" and all that is more complete.

GMan
A: 

Two different ways:

( *this ) [ index ] or this -> operator [ ] ( index )
Tanveer Badar