More problems with subscript operator

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Steve

    More problems with subscript operator

    Hi, I have a class called cList as so:

    template<class T> class cList { // base class for Lists
    private:
    protected:
    vector<T> tListOf; // field list container
    public:
    void Add(const T& t) {tListOf.push_b ack(t);} // add new object to list
    unsigned int Count() { return tListOf.size(); } // number of list items

    cList(); // default constructor
    cList(const cList&); // copy constructor
    cList& operator=(const cList&); // assignment constructor
    virtual ~cList(); // destructor

    T& operator[](int& pos) {return tListOf[pos];} // subscript operator
    const T& operator[](const int& pos) {return tListOf[pos];} // subscript
    operator
    };


    This is inherited by another class, cDataList, and another, cResultList. The
    data list object is a list of cData objects, and the result list is a list
    of cResult objects.

    class cResultList : public cList<cResult> {
    private:
    // some stuff
    public:
    // c'tors etc
    };

    class cDataList : public cList<cData> {
    private:
    // some stuff
    public:
    // c'tors etc

    cResultList Results;
    };


    The cDataList object contains a cResultList object called Results.

    I then have a class called cDCF like so:

    class cDCF {
    private:
    // some stuff
    public:
    // c'tors etc
    cDataList Data;
    };

    My problem is, I'm struggling to access the elements of Results (the cResult
    class has a 'value' member):

    cDCF *dcf = new cDCF(myfilename );

    float f = dcf->Data[1].Results[1].value;

    This gives a compiler error saying:
    operator+ not implemented in type cResultList for arguements of type 'int'

    however, if I use this:

    cDCF *dcf = new cDCF(myfilename );
    cData d = dcf->Data[1];
    float f = d.Results[1].value;

    this works. Now I know it's something to do with how I'm using the subscript
    operator, but I'm not sure what. Can anybody see what I'm doing wrong
    please?

    Thanks for your time,
    Steve


  • Gianni Mariani

    #2
    Re: More problems with subscript operator

    Steve wrote:[color=blue]
    > Hi, I have a class called cList as so:[/color]

    It would really help if you posted a complete compilable example that
    demonstrated your issue.
    [color=blue]
    >
    > template<class T> class cList { // base class for Lists
    > private:
    > protected:
    > vector<T> tListOf; // field list container
    > public:
    > void Add(const T& t) {tListOf.push_b ack(t);} // add new object to list
    > unsigned int Count() { return tListOf.size(); } // number of list items
    >
    > cList(); // default constructor
    > cList(const cList&); // copy constructor
    > cList& operator=(const cList&); // assignment constructor
    > virtual ~cList(); // destructor
    >
    > T& operator[](int& pos) {return tListOf[pos];} // subscript operator
    > const T& operator[](const int& pos) {return tListOf[pos];} // subscript
    > operator[/color]

    I suspect the operator above is probably not what you want.

    T& operator[](int pos) {return tListOf[pos];}
    const T& operator[](int pos) const {return tListOf[pos];}

    I think passing an (int) or a (const int &) is really not going to be an
    issue but I think you never want to oass an (int &) becuase that limits
    what can be passed in as a subscript parameter.

    The const [] operator need to be a const function.

    This *might* be the issue you have, I don't know.
    [color=blue]
    > };
    >
    >
    > This is inherited by another class, cDataList, and another, cResultList. The
    > data list object is a list of cData objects, and the result list is a list
    > of cResult objects.
    >
    > class cResultList : public cList<cResult> {
    > private:
    > // some stuff
    > public:
    > // c'tors etc
    > };
    >
    > class cDataList : public cList<cData> {
    > private:
    > // some stuff
    > public:
    > // c'tors etc
    >
    > cResultList Results;
    > };
    >
    >
    > The cDataList object contains a cResultList object called Results.
    >
    > I then have a class called cDCF like so:
    >
    > class cDCF {
    > private:
    > // some stuff
    > public:
    > // c'tors etc
    > cDataList Data;
    > };
    >
    > My problem is, I'm struggling to access the elements of Results (the cResult
    > class has a 'value' member):
    >
    > cDCF *dcf = new cDCF(myfilename );
    >
    > float f = dcf->Data[1].Results[1].value;
    >
    > This gives a compiler error saying:
    > operator+ not implemented in type cResultList for arguements of type 'int'
    >
    > however, if I use this:
    >
    > cDCF *dcf = new cDCF(myfilename );
    > cData d = dcf->Data[1];
    > float f = d.Results[1].value;
    >
    > this works. Now I know it's something to do with how I'm using the subscript
    > operator, but I'm not sure what. Can anybody see what I'm doing wrong
    > please?
    >
    > Thanks for your time,
    > Steve
    >
    >[/color]

    Comment

    • Steve

      #3
      Re: More problems with subscript operator

      Hi Gianni

      [color=blue]
      > T& operator[](int pos) {return tListOf[pos];}
      > const T& operator[](int pos) const {return tListOf[pos];}[/color]


      This fixed the problem, many thanks.

      [color=blue]
      >
      > I think passing an (int) or a (const int &) is really not going to be an
      > issue but I think you never want to oass an (int &) becuase that limits
      > what can be passed in as a subscript parameter.
      >
      > The const [] operator need to be a const function.
      >[/color]

      I'm still trying to get to grips with when to pass by reference and when not
      to.

      Thanks again,
      Steve


      Comment

      • Gianni Mariani

        #4
        Re: More problems with subscript operator

        Steve wrote:[color=blue]
        > Hi Gianni
        >
        >
        >[color=green]
        >>T& operator[](int pos) {return tListOf[pos];}
        >>const T& operator[](int pos) const {return tListOf[pos];}[/color]
        >
        >
        >
        > This fixed the problem, many thanks.
        >
        >
        >[color=green]
        >>I think passing an (int) or a (const int &) is really not going to be an
        >>issue but I think you never want to oass an (int &) becuase that limits
        >>what can be passed in as a subscript parameter.
        >>
        >>The const [] operator need to be a const function.
        >>[/color]
        >
        >
        > I'm still trying to get to grips with when to pass by reference and when not
        > to.[/color]

        The only time you want to pass by (non const) reference is when you want
        the function being called to modify the caller's parameter.

        Passing by value or by const & depends on what you're doing. For
        example, passing a large struct by value may be unwise because the
        construction and destruction are expensive in resources, passing an int
        by value is probably less expensive resource wise than passing by
        reference. However, there is one other issue, passing a by const &
        means that you are required not to modify the parameter while in the
        function being called otherwise you will get unpredictable behaviour.

        See this:

        int x = 2;

        int func( const int & z )
        {
        x = z + 1;
        return z * x;
        }

        int main()
        {
        return func( x );
        }

        The return value from main is undefined. This is because func()
        modifies it's own const parameter meaning that it's not really const
        after all. The compiler may make the optimization of reading the value
        of z only once and use it in both expressions (note that the compiler is
        free to not make the optimization according to the standard).

        If we declare func() as "int func( int z )" then there is a copy of the
        value x passed into the function.

        However, this is rarely an issue and the cost of making a copy is
        usually far greater than passing a reference.


        Comment

        • Woebegone

          #5
          Re: More problems with subscript operator

          Hi Steve,
          [color=blue][color=green]
          > > I'm still trying to get to grips with when to pass by reference and when[/color][/color]
          not[color=blue][color=green]
          > > to.[/color]
          >
          > The only time you want to pass by (non const) reference is when you want
          > the function being called to modify the caller's parameter.
          >
          > Passing by value or by const & depends on what you're doing.[/color]

          Another consideration is whether you want polymorphic behaviour within your
          function. A value parameter will always be read according to it's static
          type, while a reference or pointer parameter behaves according to it's
          dynamic type. Here's an example:

          #include <string>
          #include <iostream>

          class C {
          public:
          virtual const std::string name() const{
          return "class C";
          }
          };

          class D : public C {
          public:
          const std::string name() const {
          return "class D";
          }
          };

          void f_ref(const C& c) {
          std::cout << "f_ref sees: " << c.name() << "\n";
          }

          void f_ptr(const C* c) {
          std::cout << "f_ptr sees: " << c->name() << "\n";
          }

          void f_val(const C c) {
          std::cout << "f_val sees: " << c.name() << "\n";
          }

          int main() {
          D d;
          f_ref(d);
          f_ptr(&d);
          f_val(d);
          return 0;
          }

          Output:
          f_ref sees: class D
          f_ptr sees: class D
          f_val sees: class C
          --
          Regards,
          Sean.


          Comment

          • Steve

            #6
            Re: More problems with subscript operator

            Thanks for the advice guys, your wisdom is always appreciated!

            Steve.

            "Woebegone" <woebegoneDELET E@THIScogeco.ca > wrote in message
            news:XEanc.5496 $_12.367@read1. cgocable.net...[color=blue]
            > Hi Steve,
            >[color=green][color=darkred]
            > > > I'm still trying to get to grips with when to pass by reference and[/color][/color][/color]
            when[color=blue]
            > not[color=green][color=darkred]
            > > > to.[/color]
            > >
            > > The only time you want to pass by (non const) reference is when you want
            > > the function being called to modify the caller's parameter.
            > >
            > > Passing by value or by const & depends on what you're doing.[/color]
            >
            > Another consideration is whether you want polymorphic behaviour within[/color]
            your[color=blue]
            > function. A value parameter will always be read according to it's static
            > type, while a reference or pointer parameter behaves according to it's
            > dynamic type. Here's an example:
            >
            > #include <string>
            > #include <iostream>
            >
            > class C {
            > public:
            > virtual const std::string name() const{
            > return "class C";
            > }
            > };
            >
            > class D : public C {
            > public:
            > const std::string name() const {
            > return "class D";
            > }
            > };
            >
            > void f_ref(const C& c) {
            > std::cout << "f_ref sees: " << c.name() << "\n";
            > }
            >
            > void f_ptr(const C* c) {
            > std::cout << "f_ptr sees: " << c->name() << "\n";
            > }
            >
            > void f_val(const C c) {
            > std::cout << "f_val sees: " << c.name() << "\n";
            > }
            >
            > int main() {
            > D d;
            > f_ref(d);
            > f_ptr(&d);
            > f_val(d);
            > return 0;
            > }
            >
            > Output:
            > f_ref sees: class D
            > f_ptr sees: class D
            > f_val sees: class C
            > --
            > Regards,
            > Sean.
            >
            >[/color]


            Comment

            Working...