Josh
Josh

Reputation: 211

C++ templates question

template <class T>
class ListNode {

public:
    T* data;
        ListNode<T>* next;
}

Lets say I have got a list node template and somewhere in the code I want to get a copy of the data - meaning not a copy of a pointer to data (T*) but a new pointer (T*) which will point to another place in the memory which have the same information there.

How can I do it when using C++ templates? How can I copy (*data) if I don't know what is the type of T.

Upvotes: 0

Views: 188

Answers (4)

J Evans
J Evans

Reputation: 1122

The compiler knows the type of T. What is does not know is how many instances of T are pointed to. In terms of getting a practical implementation, the short answer would be don't use pointer types. Use containers instead. Since you are copying the node data anyway the overhead is minimal. Explicit example below:

template <class T>
class ListNode {
public:
    // use a vector as the  container
    std::vector<T> data;
    ListNode<T>* next;
    // initializer from pointer primitive
    ListNode(const T* ps,size_t elements)
    {
        data.assign(ps,ps+elements);
    }
    // copy templated instance
    ListNode(const ListNode& arg)
    {
        data = arg.data;
    }
    // assignment
    ListNode& operator=(const ListNode& arg)
    {
        if (this != &arg)
        {
            data = arg.data;
        }
        return *this;
    }
};

Actual usage would be similar to this:

{
    const char* ps = "Hello World";
    ListNode<char> ln1(ps,strlen(ps));
    ListNode<char> ln2 = ln1;
}

You can, of course, get much more complicated solutions but they will all involve keeping track of the number of instances of type T to which your pointer points.

Upvotes: 1

iammilind
iammilind

Reputation: 69988

When creating a copy of a templated type, practically you need not worry about the type as such and live that task on the copy constructor or assignment operator of that type:

template <class T>
class ListNode {
public:
    T* data;
    ListNode<T>* next;
    T* getCopy() { new T(*data); } // get copy of "data"
};

Suppose you use this ListNode<T> for class A, then you can have a copy constructor defined for A (and assignment operator as well):

class A {
public:
  A(const A& copy);
};

Now when ListNode<T>::getCopy() is called, it will call the copy constructor of A internally.

Upvotes: 0

Zan Lynx
Zan Lynx

Reputation: 54325

Use operator= or the copy constructor. It's standard practice that both of these will produce a copy of the object.

So, for example:

T *p = other_pointer;
*p = *data;

Or

T* copy = new T(*data);

Upvotes: 0

Doug T.
Doug T.

Reputation: 65599

T has to be copy-constructable so that you can do

   template <class T>
   ListNode<T>::ListNode(const ListNode<T>& src)
   {

        ...
        // given a preexisting copy, src, create a new T to
        // perform a copy
        T* destT = new T(*srcT);
   }

If T has a copy constructor, this will work. If it doesn't, the compiler will give you an error (probably a very cryptic one)

Upvotes: 0

Related Questions