5

In all books I've read until now, they said that C++ templates generate one instance of code for each type we use.

On the other and, the books said that in C# the code is reused.

So I made a search in many books and I found in one very old book the following examples for C#.

1) Value types

List<int> intList1  = new List<int>();
List<int> intList2  = new List<int>();
List<bool> boolList = new List<bool>();

In this case (value types) the compiler generates ONE instance of code for both intList1 and intList2 (same type) and ONE instance of code for boolList.

2) Reference types

List<Dog> dogList1 = new List<Dog>();
List<Dog> dogList2 = new List<Dog>();
List<Cat> catList  = new List<Cat>();

In this case (reference types) the compiler generates JUST ONLY ONE instance of code for dogList1, dogList1 and catList because as long as it can represent the pointer to the object, all reference types can share a single implementation.

This is very clear to me (as a C++ dev) but I'm courious about the same thing concerning c++ templates.

Long before C # was created, C++ had value types and reference types too.

So lets rewrite the avove examples in C++

1) Value types

vector<int> intList1;
vector<int> intList2;
vector<bool> boolList;

In this case I have no doubt that intList1 and intList2 share the same code and boolList needs another implementation

2) Reference types

vector<Dog *> dogList1;
vector<Dog *> dogList2;
vector<Cat *> catList;

My question is:

Can I conclude that in the second case (vectors of pointers) all share the same template instantiation as long as are all vector pointers ( vector<Dog *> and vector<Cat *> ) and all pointers are of the same size (32 or 64 bit depending on the platform)?

m.s.
  • 16,063
  • 7
  • 53
  • 88
Adriaan
  • 51
  • 1
  • It is implementation specific. Notice that C++11 has `extern template` – Basile Starynkevitch Oct 19 '15 at 10:54
  • 1
    "C++ had value types and reference types too" - There's no distinction between "value" and "reference" types. You can have pointer to `int` and you could use `Dog` as value. – el.pescado - нет войне Oct 19 '15 at 10:55
  • 1
    For me the question should be called "binary" reuse more than anything. – Bartek Banachewicz Oct 19 '15 at 10:56
  • 1
    Isn't this very much implementation-defined? AFAIK the language standard makes very little assumptions on binary representation... – DevSolar Oct 19 '15 at 10:56
  • A pointer is not a reference type. C++ doesn't have (and have never had, and will never have) "reference types" as known in C#. Also, C++ templates are quite different from C# generics. – molbdnilo Oct 19 '15 at 10:58
  • Related question [here](http://stackoverflow.com/questions/15168924/gcc-clang-merging-functions-with-identical-instructions-comdat-folding) evidences how identical function code may be generated but still consolidated during linking. – Tony Delroy Oct 19 '15 at 11:07
  • @molbdnilo: when I wrote in C# Dog d = new Dog() what's the content of *d*? Is or is not the *address* in memory where the object *d* is located? If so we can conclude that *d* is a pointer to an object of class Dog. IMHO – Adriaan Oct 19 '15 at 11:36
  • @Adriaan The value of `d` is a reference (in the C# sense). That value is not of a reference type; it's a reference to an instance of a reference type (`Dog`). Whether that value is represented by the object's address is an implementation detail and the language doesn't require any particular representation. The C# implementation details are also 100% irrelevant to the question of whether "reference types" exist in C++. – molbdnilo Oct 19 '15 at 12:19
  • @el.pescado: and this is the POWER of C++: I can have a value type _int_ and a reference type _int*_ as I can have a _Dog_ as value and _Dog*_ as reference type. I still don´t understand why C# and Java devs are relutant to consider a **reference** as a variable who holds the **address of** something. Note: don´t confuse with the misleading concept of C++ _reference_ wich means **alias** – Adriaan Oct 19 '15 at 13:31
  • @Adriaan: I don't see what's misleading in C++ references. I think calling a pointer a "reference type" is more misleading. – DevSolar Oct 20 '15 at 09:51

2 Answers2

4

(There's a fair bit of confusion in your question, but let me skip over that and address the actual question).

No you cannot assume that.

This is chiefly because pointers do not necessarily have to be the same size, irrespective of whether your system is 32 or 64 bit.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • This might be a good information complement: http://stackoverflow.com/q/6751749/1147772 – Drax Oct 19 '15 at 11:05
  • @Bathsheba: «On 32-bit Windows, the integer, long, and pointer data types are all the same size—32 bits. This convenient uniformity in data type sizes has been a boon to clever C programmers, many of whom have come to take it for granted. On 64-bit Windows, however, this assumption of uniformity is no longer valid. Pointers are now 64 bits in length, but integer and long data types remain the same size as before—32 bits.» https://msdn.microsoft.com/en-us/library/ff565649%28v=vs.85%29.aspx – Adriaan Oct 19 '15 at 13:22
1

Probably, you can use static variables to check this, something like this:

#include <iostream>
using namespace std;

template <typename T>
class Wrapper
{
public:
    static int count;
    T d_wrapped;

    Wrapper(T i_wrap) : d_wrapped(i_wrap)
    {
        ++count;
    }
};

template <typename T>
int Wrapper<T>::count = 0;

int main() {
    Wrapper<int> wi(1);
    Wrapper<int> wi2(2);
    Wrapper<float> wf(1.0f);

    Wrapper<int*> wip(new int());
    Wrapper<float*> wfp(new float());

    cout << Wrapper<int>::count << ' ' << Wrapper<float>::count << '\n' <<
            Wrapper<int*>::count << ' ' << Wrapper<float*>::count << '\n';
    return 0;
}

Ideone live code

Launch on ideone shows that even for pointers we have separate static variables.

alexeykuzmin0
  • 6,344
  • 2
  • 28
  • 51
  • 1
    This is an interesting way of checking, but perhaps the compiler could condense the code if the `static` was *not* present. – Bathsheba Oct 19 '15 at 12:04