Reputation:
I have a class like this:
template <class T>
class bag
{
private:
typedef struct{T item; unsigned int count;} body;
typedef struct _node{_node* prev; body _body; _node* next;}* node;
struct iterator{
enum exception{NOTDEFINED, OUTOFLIST};
body operator*();
explicit iterator();
explicit iterator(const iterator&);
iterator& operator=(const iterator&);
iterator& operator++(int);
iterator& operator--(int);
bool operator==(const iterator&) const;
bool operator!() const;
private:
node current;
friend class bag;
};
node head;
node foot;
iterator _begin;
iterator _end;
/* ... */
public: /* ... */
bag();
const iterator& begin;
const iterator& end;
};
In the bag() I have to set the reference begin to _begin, and end to _end.
begin = _begin;
end = _end;
But I think this line
begin = _begin;
invokes bag::iterator::operator=() function.
How can i avoid that?
Upvotes: 0
Views: 174
Reputation: 8834
A class containing reference members essentially becomes unassignable (because references can't be reseated).
It looks like your Bag is duplicating the same data in several members (extra burden to keep duplicated values in synch).
Instead you could do what the standard library does: create and return the iterator by value from begin()
and end()
methods.
template <class T>
class bag
{
struct node { /*...*/ }
/* ... */
node* head; //why would you want to typedef away that these are pointers?
node* tail;
public:
class iterator {
iterator(node*);
/* ... */
};
iterator begin() { return iterator(head); }
iterator end() { return iterator(tail); }
//also you might need const_iterators
};
Upvotes: 0
Reputation: 2225
As Mike said, you have to initialise a reference where you declare it, you can't change it afterwards. The initialiser list is the most idiomatic solution if you don't have to modify the references once the object is constructed, but in the case you foresee you have to change them, there are still the good old pointers:
public: /* ... */
bag();
iterator *begin;
iterator *end;
Upvotes: 0
Reputation: 254431
References can't be assigned, only initialised. So you will need to initialise them in the constructor's initialisation list:
bag() : begin(_begin), end(_end) {}
However, it's more conventional (and also reduces the class size) to get these using accessor functions rather than public references:
const iterator& begin() {return _begin;}
const iterator& end() {return _end;}
Upvotes: 3