0

I have a program I wrote for a class back in 2000 that I thought I would try to run just for the fun of it. It used to compile back in 2000, but I'm getting a bunch of errors now. I pretty much haven't looked at C++ code since that class, so I'm a bit bewildered. I resolved a bunch of complaints about iostream.h & list.h (putting "std::" in front of a bunch of things like std::cerr, etc). I don't know if that caused the current errors, or whether there's something inherently wrong with my iterators, but the only thing left to resolve involves a bunch of iterator constructors. First, here is a sample of the errors:

SolutionList.cpp:10:22: error: no matching constructor for initialization of 'PieceList::iterator'
        PieceList::iterator i=rhs.first();
                            ^ ~~~~~~~~~~~
./PieceList.h:27:5: note: candidate constructor not viable: expects an l-value for 1st argument
                                iterator(iterator& rhs){data = rhs.data;}
                                ^
./PieceList.h:28:5: note: candidate constructor not viable: no known conversion from 'PieceList::iterator' to 'std::list<Piece>::iterator &'
      (aka '__list_iterator<value_type, __void_pointer> &') for 1st argument
                                iterator(std::list<Piece>::iterator& rhs){data = rhs;}
                                ^
./PieceList.h:26:5: note: candidate constructor not viable: requires 0 arguments, but 1 was provided
                                iterator(){}
                                ^

And here's what I believe is the relevant portion of code:

class PieceList
{
    public:
        PieceList(){}
        PieceList(PieceList& rhs){pieces = rhs.pieces;}
        PieceList(std::list<Piece>& rhs){pieces = rhs;}

        friend std::ifstream& operator>>(std::ifstream&,PieceList&);
        friend std::istream& operator>>(std::istream&,PieceList&);

        class iterator
        {
            public:
                friend class PieceList;

                iterator(){}
                iterator(iterator& rhs){data = rhs.data;}
                iterator(std::list<Piece>::iterator& rhs){data = rhs;}

                Piece operator*(){return *data;}
                iterator& operator=(iterator& rhs){data=rhs.data;return *this;}
                iterator& operator=(std::list<Piece>::iterator& rhs){data = rhs;return *this;}
                bool operator==(iterator& rhs){return data==rhs.data;}
                bool operator==(const iterator& rhs) const{return data==rhs.data;}
                bool operator!=(iterator rhs){return data != rhs.data;}
                iterator& operator++(){++data;return *this;}
                iterator& operator--(){--data;return *this;}
            private:
                std::list<Piece>::iterator data;
        };

        iterator first(){iterator i;i.data=pieces.begin();return i;}
        iterator last(){iterator i;i.data=pieces.end();return i;}

    private:
        std::list<Piece> pieces;
};

So I know that it doesn't like the second constructor, but I'm not sure how to fix it. I couldn't make sense of any of my google results from googling the errors. Can anyone point me in the right direction?

hepcat72
  • 890
  • 4
  • 22
  • Incidentally, the program solves soma cubes where the number of dimensions is a command-line parameter. I was telling someone about it last week and was pretty proud I'd solved 90 degree rotations in any number of dimensions. I kinda want put it on github or something or maybe rewrite it all together, but it would be nice if I could just get it to run. – hepcat72 Jul 18 '15 at 20:17

1 Answers1

1

You cannot bind temporaries to non-const references.

    iterator(iterator const& rhs) : data(rhs.data) {}
    iterator(std::list<Piece>::iterator rhs) : data(rhs) {}

Note that iterators are conventially passed by value

Live On Coliru

#include <iterator>
#include <list>
#include <string>
#include <iostream>

struct Piece {
    std::string name;
};

class PieceList
{
    public:
        PieceList(){}
        PieceList(PieceList const& rhs){pieces = rhs.pieces;}
        PieceList(std::list<Piece> const& rhs){pieces = rhs;}

        friend std::ifstream& operator>>(std::ifstream&,PieceList&);
        friend std::istream& operator>>(std::istream&,PieceList&);

        class iterator
        {
            public:
                friend class PieceList;

                iterator(){}
                iterator(iterator const& rhs) : data(rhs.data) {}
                iterator(std::list<Piece>::iterator rhs) : data(rhs) {}

                Piece operator*(){return *data;}
                iterator& operator=(iterator& rhs){data=rhs.data;return *this;}
                iterator& operator=(std::list<Piece>::iterator& rhs){data = rhs;return *this;}
                bool operator==(iterator& rhs){return data==rhs.data;}
                bool operator==(const iterator& rhs) const{return data==rhs.data;}
                bool operator!=(iterator rhs){return data != rhs.data;}
                iterator& operator++(){++data;return *this;}
                iterator& operator--(){--data;return *this;}
            private:
                std::list<Piece>::iterator data;
        };

        iterator first(){iterator i;i.data=pieces.begin();return i;}
        iterator last(){iterator i;i.data=pieces.end();return i;}

    private:
        std::list<Piece> pieces;
};

int main() {
    PieceList pl { {
        { "aap" },
        { "noot" },
        { "mies" },
    } };
    for(auto it=pl.first(); it!=pl.last(); ++it) {
        std::cout << (*it).name << "\n";
    }
}

Prints

aap
noot
mies

You had a similar issue with the constructors of PieceList. Your iterator class is missing operator-> too. I'll leave that as an ExerciseForTheReader™

sehe
  • 374,641
  • 47
  • 450
  • 633
  • OK, I pasted the entirety of the rest of the class, barring the # lines. Does that address the blind? – hepcat72 Jul 18 '15 at 20:20
  • @hepcat72 yep that helped – sehe Jul 18 '15 at 20:26
  • What does the colon do in your fix? I.e. What does " : data(rhs.data)" do? – hepcat72 Jul 18 '15 at 20:31
  • It's an initializer list: search for `[c++-faq] colon constructor`: http://stackoverflow.com/questions/1711990/what-is-this-weird-colon-member-syntax-in-the-constructor?s=1|2.8949 (only 106 upvotes... some 200+ in the answers) – sehe Jul 18 '15 at 20:32
  • Awesome. That resolved the errors! Yay! Thanks so much! So fast too. I just have to propagate this fix to the other iterators and then see if anything new pops up in the errors. – hepcat72 Jul 18 '15 at 20:39
  • Alright. One of my iterator classes is a bit different than the others and is still generating errors about the != and the = operators. Should I edit my question above, post a brand new question, or is there some way to post followup questions that spawn from a current question? – hepcat72 Jul 18 '15 at 21:12
  • Post a brand new question, unless you think it's of no value to others, in which case consider just paste-binning and linking it here – sehe Jul 18 '15 at 21:13
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/83635/discussion-between-sehe-and-hepcat72). – sehe Jul 18 '15 at 21:13