After a quick review of the board, I haven't found any questions like this.
Here's my dilemma:
I want to write a container class for a group of unique objects. I want to be able to add objects (without creating duplicates), remove objects, and see if an object is contained within the list. I also need to get constant iterators to the beginning and end of the list. Here's the prototype I have so far:
/// \brief Container class for a group of unique objects.
template<class T, class List = std::list<T> >
class Group {
private:
List object; ///< \brief Object list.
public:
/// \breif Returns a constant iterator to the beginning of the
/// list.
/// \return The iterator.
List::const_iterator begin() const;
/// \brief Returns a constant iterator to the end of the list.
/// \return The iterator.
List::const_iterator end() const;
/// \brief Adds an object to the list.
/// \param obj The object to add.
/// \return Itself.
Group &operator+=(const T &obj);
/// \brief Removes an object from the list.
/// \param obj Te object to remove.
/// \return Itself.
Group &operator-=(const T &obj);
/// \brief Determines if an object is found in the list.
/// \param obj The object to find.
/// \return true if found, false otherwise.
bool has(const T &obj) const;
};
The begin() and end() functions refuse to compile because apparently List::const_iterator isn't valid. Can someone suggest an alternative?
Thanks.
P.S.: Please forgive the weird comments. They're interpreted by doxygen to automatically create my documentation for me.
P.P.S.: I've considered template<class T, class List = std::list<T>, class Iter = std::list<T>::const_iterator>
but I'm hoping there's a cleaner way of changing the list type.
(EDIT: This apparently also isn't legal.)
IMHO, your class hasn't added anything to most STL container classes other than operator+= and operator-= as ways of inserting (push_back?) and removing instead of the methods provided by the container.
So I question the usefulness of this class in the first place. STL provides the find() algorithm which will work on all STL containers just as your has() method will. And begin() and end() are just forwarders of the underlying container's begin() and end() methods.
The difference is that the operator+= won't add a duplicate object.
If I were to write:
1 2
Group<int> foo;
foo += 3 += 3;
The resulting list would contain only one value since the second 3 would be discarded. If there is an STL container that does this, please let me know as I'll be happy to use that instead.
The problem is an inherent ambiguity in the C++ grammar with respect to the scope resolution operator.
a::b::c
Could refer to namespace a, object b, type c. Or object a, type b, type c.
Or type a, type b, type c.
The compiler tries to make an intelligent guess, but it doesn't always get it right.
Using the keyword typename tells the compiler how to interpret it: