5

My Code is:

#include <iostream>

using namespace std;


template <typename T, int X>

class Test
{
   private:
    T container[X];
   public:
    void printSize();

};
template <typename T, int X>
void Test<T,X>::printSize()
{
    cout <<"Container Size = "<<X <<endl;
}


int main()
{
    cout << "Hello World!" << endl;
    Test<int, 20> t;
    Test<int, 30> t1;

    t.printSize();
    t1.printSize();
    return 0;
}

Question:

  1. How many specialization will get generated?. If I understand correctly , it generates two specializations one is for <int, 20> and another is for <int, 30>. Kindly Correct if my understanding is wrong?
  2. Is there any way to see/check the number of specializations generated by any reverse engineering?
TemplateRex
  • 69,038
  • 19
  • 164
  • 304
Whoami
  • 13,930
  • 19
  • 84
  • 140
  • 1
    This may help http://stackoverflow.com/questions/4448094/can-we-see-the-template-instantiated-code-by-c-compiler – FireAphis Apr 18 '13 at 08:26

3 Answers3

3

There are not specializations here, only instantiations (this questions explains the difference). This code generates two instantiations of the class template Test.

Community
  • 1
  • 1
Björn Pollex
  • 75,346
  • 28
  • 201
  • 283
  • I think when saying specializations he meant generated-classes. i actually dont understand why two (classes) are created, if its still an int in both times. – Ariel Pinchover Apr 18 '13 at 08:14
  • @Infested the value of `X` differs – TemplateRex Apr 18 '13 at 08:16
  • @rhalbersma ive noticed that, but its still an int. how would i write it so the "X" part doesnt make a difference? – Ariel Pinchover Apr 18 '13 at 08:19
  • @Infested: If you don't want the `X` to make a difference, make it a parameter to the constructor of `Test`. Then you cannot have a statically sized array as member though. This is the semantic difference between `std::array` and `std::vector`. – Björn Pollex Apr 18 '13 at 08:20
  • @BjörnPollex that i know also, but is there a way to hold two types in the template and with one not making a difference for different values? lets say LIST and you create LIST t1; LIST t2; it will not generate LIST twice, only instantiate t1 and t2 twice. – Ariel Pinchover Apr 18 '13 at 08:24
  • @Infested Because in your case, the template arguments are the same: `int`. Templates can have type parameters as well as non-type parameters. `X` is a non-type parameter, which means that each value of `X` creates a different instantiation (just like each different type used as the argument for a type parameter creates a different instantiation). – Angew is no longer proud of SO Apr 18 '13 at 08:28
  • @Angew so if i were to write template thatd be ok, and only generating for each T ? – Ariel Pinchover Apr 18 '13 at 08:32
  • @Infested It's as Björn Pollox states: if you want to have a compile-time `container[X]` then you will get 2 instantiations, no matter what. If you are OK with a runtime sized vector, then you only need 1. – TemplateRex Apr 18 '13 at 08:40
  • @Infested `template ` has two template parameters: a type parameter (named T) and a non-type int parameter (unnamed). Different integer values used as arguments for the non-type parameter will generate different instantiations. *Just like with any other template arguments.* – Angew is no longer proud of SO Apr 18 '13 at 08:43
  • @Angew thats what i was asking, so it doesnt make two classes that way. – Ariel Pinchover Apr 18 '13 at 11:10
  • @Infested **Yes, it does generate two.** If you have `template struct S;`, then `S` and `S` are two **absolutely distinct** classes. – Angew is no longer proud of SO Apr 18 '13 at 11:16
2

1) yes, two instantiations will be generated by the compiler, but the linker might merge functions with identical generated code (using whole program optimization e.g.), which is a cute way to reduce code bloat.

2) see this question where it is explained how gcc can generate template instantiation output.

Community
  • 1
  • 1
TemplateRex
  • 69,038
  • 19
  • 164
  • 304
0

a) There are 2 instances of specialization get created in your example.

b)There is no builtin method to support number of specialization generated for a class. If its your project you can add static count. If you want you can write your own reference count mechanism for your class. Increment static count in our constructor.

static int created = 0;
static int alive = 0;
class Test
{
counter()
    {
        created++;
        alive++;
    }
~counter()
{
  created--;
}
//Rest of class
};
shivakumar
  • 3,297
  • 19
  • 28