1

so I need to use a template class as a container, so I need to create a new associative container that's derived from STL set, so far this is what I have (Code Snippets from relevant parts).

In UpdatableSet.h

#include <set>

template <class T>
class UpdatableSet : public std::set<T>
{
public:
    UpdatableSet(){};
    ~UpdatableSet(){};
    bool add(T);
private:
    std::set<T> set;
};

add(T), this method is supposed to add the T to the set and if it was successful, return true, or return false, not sure if this is correct or not, because I don't fully understand the concepts.

template <class T>
bool UpdatableSet<T>::add(T update)
{

    if(set.insert(update).good())
    {
        return true;
    }
    else 
        return false;

}

in main

UpdatableSet<CDAlbum> updatableAlbumSet; //Want this to be a set of objects of the CDAlbum kind
updatableAlbumSet.add(theCDAlbum); //how do I use this to add to the set?

Ultimately I'm getting this compilation error

symbol in file bool UpdatableSet::add(CDAlbum) task2Main.o ld: fatal: symbol referencing errors. No output written to a.out

EDIT: So you guys were right, I've figured out that I've needed to create the methods myself instead of deriving it from set.

here's how it looks now

in UpdatableSet.h

template <class T>
class UpdatableSet
{



    public:
    UpdatableSet(){};
    ~UpdatableSet(){};
    bool add(T);
    int size();
    int begin();
    int end();
    typedef typename set<T>::iterator iterator;

    private:
    std::set<T> set;

};

template <class T>
bool UpdatableSet<T>::add(T update)
{
    return set.insert(update).second;
}

template <class T>
int UpdatableSet<T>::size()
{
    return set.size();
}

template <class T>
int UpdatableSet<T>::begin()
{
    return set.begin();
}

template <class T>
int UpdatableSet<T>::end()
{
    return set.end();
}

However I'm getting this error now "task2Main.cpp", line 67: Error: Cannot use int to initialize __rwstd::__rb_tree, std::less, std::allocator>::const_iterator.

"task2Main.cpp", line 67: Error: The operation "__rwstd::__rb_tree, std::less, std::allocator>::const_iterator != int" is illegal.

Impulse
  • 155
  • 11
  • 2
    Don't inherit from classes that were not designed to be a base class. Use a free function or composition instead. – Baum mit Augen Oct 30 '14 at 14:39
  • 2
    " I need to create a new associative container that's derived from STL set" No you don't, as that's not allowed. – Neil Kirk Oct 30 '14 at 14:40
  • 5
    Also you both inherit from set, and have it as a member. – Neil Kirk Oct 30 '14 at 14:40
  • 1
    The function can be simplified to `return insert(update).second;` making it rather pointless (and inefficient, since it involves unnecessary copying). In general it's not a great idea to inherit from classes that weren't designed for that; consider writing non-member functions instead. If you must use inheritance, then don't also have a private member of the same type. In any case, your problem is that you need to define the template in a header, not a source file. – Mike Seymour Oct 30 '14 at 14:42

1 Answers1

2

Don't inherit from std::set<T>. Using it as a private member is strongly preferred. And especially don't do both - what would that even mean? Your object both IS-A set and HAS-A set? No.

Secondly, this line:

if(set.insert(update).good())

The set::insert() method returns a pair<iterator, bool>. There is no good() method there. If you want to check for success, you want to do:

if (set.insert(update).second)

But since you're effectively just forwarding the result anyway, you should do:

return set.insert(update).second;
Barry
  • 286,269
  • 29
  • 621
  • 977
  • The issue here is that I literally have to derive my container from set, at least that's how I've interpreted it. as this is for an assignment, and I'm not allowed to change my main file. The issue is this pdatableSet::iterator p=updatableAlbumSet.begin(); p!=updatableAlbumSet.end() where it makes an iterator for the container – Impulse Oct 30 '14 at 14:49
  • 1
    You can write your own begin()/end() to just return your member set's begin()/end(), and typedef the iterator. – Barry Oct 30 '14 at 14:52
  • So I've changed it so it no longer derives from set, how would I go about with the iterator? – Impulse Oct 30 '14 at 14:56
  • I've made the suggested changes, and I think it's working, but I'm getting casting errors that I don't understand now. – Impulse Oct 30 '14 at 15:13