0

If I have a templated class definition in list.h:

template <class T>;
class list {
    list *next;
    T *data;

    list(T *data){
        this->next = NULL;
        this->data = data;
    }
    void concat(T *data){
        this->concat(new list<T>(data));
    }
    void concat(list<T> *sublist){
        if (this->next != NULL){
            this->next->concat(sublist);
        } else {
            this->next = sublist;
        }
    }
}

Then if I have main.cpp:

class bar {
    bar(){

    }
}

class baz {
    baz(){

    }
}

void main(){
    new list<bar>(new bar());
    new list<baz>(new baz());
}

And then I ran:

gcc -c main.cpp
  1. How does the code get put into translation units?
  2. Does the translation unit of main.cpp have 2 versions of list?
  3. What if list we included in another translation unit, would it appear in both?
chacham15
  • 13,719
  • 26
  • 104
  • 207
  • 3
    First of all, you shouldn't be doing this because you'll get linker errors due to the generic definition not being part of the translation unit with the instantiation. Second, both `new` uses are pointless (the list should probably store `T` as well). Finally, it's `int main`, not `void main`. – chris Feb 22 '14 at 06:24
  • from what i know a template implementation and definition must be in the same file for proper linkage. clearly that's not what your doing. – Zuko Feb 22 '14 at 06:27
  • @chris fixed the question (the void main is a shorthand which works with certain compilers). I dont understand why the new uses are pointless..because the result of the new isnt stored? I just wanted to make the compiler template the class. The list stores `T*`, why would it need to store `T`? – chacham15 Feb 22 '14 at 06:32

1 Answers1

4

When you specialize the template the code will be placed in the translation unit where the specialization occurs.

If you use a template over and over in separate translation units, you will find that each translation unit gets a copy of the code. This is called code bloat, and is one of the major drawbacks to template use.

You can declare template specializations, and place the code for those inside a single translation unit, but then you will not be able to create new specializations with out the same linker issue you have here.

To # 2: Some compilers will use a single definition when the types are similar enough. For example storing a pointer. You can create a dozen different pointer types and only the code that handles them as separate types will need to be replicated with type specialization. But this is highly compiler dependent.

Dan
  • 2,460
  • 2
  • 18
  • 12
  • 1
    Ah ha, that is what I was looking for. So if I do `nm main.o` I should expect to see all the functions belonging to `list` and `list`? – chacham15 Feb 22 '14 at 06:34
  • I'm not familiar with nm, but it seems like it would have taken you less time to do that and take a look rather than ask. If you generate a list file or a public symbols file then yes you should see some mangled form of 'List'.. like this destructor for TGrowableArray: PUBLIC ??1?$TGrowableArray@UListEntry@CBvhList@@VCSimpleAllocator@@V?$TTypeConstructor@UListEntry@CBvhList@@@@@@QAE@XZ ; TGrowableArray >::~TGrowableArray > – Dan Feb 22 '14 at 22:32