B
Belebele
Suppose that I have a method that returns references to "elements" in
an iterator, and a method to advance the iterator:
class Element { /* ... */ };
class Iterator {
public:
Element& operator*() const;
Iterator& operator++();
/* ... */
};
Now, I also want the clients of the iterator to know that the
reference to element returned by the operator* is only valid
temporarily. That is, clients of the iterator are not supposed to hold
the element reference beyond the next call to operator++, for it will
be dangling. See below:
Iterator iter(/* ... */);
Element &e = *iter;
/* Do something with e */
++iter; // At this point the reference e becomes dangling.
I would like to convey that semantic constraint to the client. A
comment would probably be sufficient. However, I would like to explore
the possibility of expressing the constraint in code.
It occurred to me to use and ancillary class to do so:
struct WillDangleRef { // Ancillary class
operator Element&() const;
private:
WillDangleRef(WillDangleRef const& ); // Hidden. Not Implemented
Element &element_;
WillDangleRef(Element& e): element_(e) {}
};
class Iterator {
public:
WillDangleRef operator*() const; // The operator* now returns
an object that
// can only be
used for conversions into Element&
Iterator& operator++();
/* ... */
};
The WillDangleRef temporary will be destructed right after the
statement that contains the call to the operator*, which gives a clue
as to the transient nature of the reference that it can be converted
into. That leaves clients with the only choice of using the reference
as a parameter to a function, which I do not like very much because I
feel is too restrictive:
void doSomethingWithE(Element& e);
Iterator iter(/* ... */);
doSomethingWithE(*iter);
++iter; // At this point the temporary returned by *iter is gone.
Could you please comment? Any other ideas?
Thanks:
Belebele
an iterator, and a method to advance the iterator:
class Element { /* ... */ };
class Iterator {
public:
Element& operator*() const;
Iterator& operator++();
/* ... */
};
Now, I also want the clients of the iterator to know that the
reference to element returned by the operator* is only valid
temporarily. That is, clients of the iterator are not supposed to hold
the element reference beyond the next call to operator++, for it will
be dangling. See below:
Iterator iter(/* ... */);
Element &e = *iter;
/* Do something with e */
++iter; // At this point the reference e becomes dangling.
I would like to convey that semantic constraint to the client. A
comment would probably be sufficient. However, I would like to explore
the possibility of expressing the constraint in code.
It occurred to me to use and ancillary class to do so:
struct WillDangleRef { // Ancillary class
operator Element&() const;
private:
WillDangleRef(WillDangleRef const& ); // Hidden. Not Implemented
Element &element_;
WillDangleRef(Element& e): element_(e) {}
};
class Iterator {
public:
WillDangleRef operator*() const; // The operator* now returns
an object that
// can only be
used for conversions into Element&
Iterator& operator++();
/* ... */
};
The WillDangleRef temporary will be destructed right after the
statement that contains the call to the operator*, which gives a clue
as to the transient nature of the reference that it can be converted
into. That leaves clients with the only choice of using the reference
as a parameter to a function, which I do not like very much because I
feel is too restrictive:
void doSomethingWithE(Element& e);
Iterator iter(/* ... */);
doSomethingWithE(*iter);
++iter; // At this point the temporary returned by *iter is gone.
Could you please comment? Any other ideas?
Thanks:
Belebele