jizanthapus
jizanthapus

Reputation: 159

Initialize generic templated container

I'm trying to write a general container (called 'tcontainer_t') that it's inner implementation could use vector or list, and a T type, according to the user's will. Problem arise when in main, when I try to create a 'tcontainer_t' object - no one knows before run time if the container type is vector or list.

//tcontainer_t.h

#include <vector>
#include <list>
using namespace std;

template <class T, class Container >
class tContainer_t {
private:
    Container container;
    typedef typename Container::iterator iter_t;
    iter_t it;

public:
    tContainer_t();
    tContainer_t<T, Container>(const tContainer_t<T, Container>& other);
    tContainer_t<T, Container>& operator=(const tContainer_t<T, Container>& classObj);
    virtual ~tContainer_t();

};

#endif /* TCONTAINERT_H_ */

the cpp file is:

 // tContainert.cpp

#include "tContainer_t.h"

//  default constructor
template < class T, class Container >
tContainer_t<T, Container>::tContainer_t() {

    this->container = new Container;   //C2679 binary '=' no operator found which takes...

}

//   copy constructor
template < class T, class Container >
tContainer_t<T, Container>::tContainer_t(const tContainer_t<T, Container>& other) {


}

//operator "="
template < class T, class Container >
tContainer_t<T, Container>& tContainer_t<T, Container>::operator=(const tContainer_t<T, Container>& classObj) {
    if (this != &classObj){
   }
    return *this;
}


template < class T, class Container >
tContainer_t<T, Container>::~tContainer_t() {
    // TODO Auto-generated destructor stub
}

and main is:

    int main() {

    tContainer_t<int, vector<int*> > vContainer;

    return 0;
}

please ignore destructor and operator "=" - both exist, I eliminated the code to clarify my question. Compilation Error pops at this line:

this->container = new Container;  

And I know it's not the right way to do it.

but how can I instantiate vector or list using this? what should be written in the constructor?

Thanks!

Upvotes: 0

Views: 599

Answers (2)

Arun
Arun

Reputation: 20383

First and foremost, I feel compelled to point out the following.

Scott Meyers, Effective STL

Item 2: Beware the illusion of container-independent code

The STL is based on generalization. Arrays are generalized into containers and parameterized on the types of objects they contain. Functions are generalized into algorithms and parameterized on the types of iterators they use. Pointers are generalized into iterators and parameterized on the type of objects they point to.

That’s just the beginning. Individual container types are generalized into sequence and associative containers, and similar containers are given similar functionality. Standard contiguous-memory containers (see Item 1) offer random-access iterators, while standard node-based containers (again, see Item 1) provide bidirectional iterators. Sequence containers support push_front and/or push_back, while associative containers don’t. Associative containers offer logarithmic-time lower_bound, upper_bound, and equal_range member functions, but sequence containers don’t.

http://my.safaribooksonline.com/book/programming/cplusplus/9780321545183/containers/ch01lev1sec2

The class template

template <class T, class Container >
class tContainer_t {

have T and Container as separate independent template parameters. Doesn't that defeat the goal as we see in the following usage?

tContainer_t<int, vector<int*> > vContainer;

int and int * are quite different.

Upvotes: 1

celtschk
celtschk

Reputation: 19721

If all you want is a default-constructed container, you don't need to write anything at all; the compiler does that for you.

If you want to initzialize the container to something different, you use a constructor initializer. For example, let's assume Container has a constructor taking an initial size (as the standard containers have), then you could write

template<class T, class Container>
 tContainer_t<T, Container>::tContainer_t():
  container(25) // make a container with 25 elements
{
}

Note that in C++, unlike e.g. in Java, the member variable container is an actual object of type Container, not just a reference to one. new Container created one on the heap and returns a pointer to that. So what you are trying to do is to assign a pointer to Container to a Container, which fails because Container has no constructor taking a pointer to Container.

Note that if you were to dereference the pointer returned by new, it would compile (assuming Container is copyable, which for standard containers just means the contained type is), but still not do what you intend: It would create a Container object on the heap, assign it to the container member (which means copying all the content into the object container), and then you'd be left with a memory leak because the pointer returned by new is temporary and nowhere assigned, and especially not deleted.

Upvotes: 1

Related Questions