1

In c# static members are unique for each generic class like in this example

using System;

//A generic class
public class GenTest<T>
{
  //A static variable - will be created for each type on refraction
  static CountedInstances OnePerType = new CountedInstances();

  //a data member
  private T mT;

  //simple constructor
  public GenTest(T pT)
  {
    mT = pT;
  }
}

//a class
public class CountedInstances
{
  //Static variable - this will be incremented once per instance
  public static int Counter;

  //simple constructor
  public CountedInstances()
  {
    //increase counter by one during object instantiation
    CountedInstances.Counter++;
    Console.WriteLine(Counter);
  }
}

public class staticTest {
  static void Main(string[] args) {
    //main code entry point
    //at the end of execution, CountedInstances{{Not a typo|.}}Counter = 2
    GenTest<int> g1 = new GenTest<int>(1);
    GenTest<int> g11 = new GenTest<int>(11);
    GenTest<int> g111 = new GenTest<int>(111);
    GenTest<double> g2 = new GenTest<double>(1.0);
  }
}

from http://en.wikipedia.org/wiki/Generic_programming

What about c++? I have tried out to check that myself but translation to c++ seems to ignore the static member.

#include <iostream>
using namespace std;

class CountedInstances {
public:
  static int Counter;
  CountedInstances() {
    Counter++;
    cout << Counter << endl;
  }
};

int CountedInstances::Counter = 0;

template<class T> class GenTest {
  static CountedInstances OnePerType;
  T mT;
public:
  GenTest(T pT) {
    mT = pT;
  }
};

template<class T> CountedInstances GenTest<T>::OnePerType = CountedInstances();

int main() {
  GenTest<int> g1(1);
  GenTest<int> g11(11);
  GenTest<int> g111(111);
  GenTest<double> g2(1.0);
  cout << CountedInstances::Counter << endl;
  //CountedInstances c1;
  //CountedInstances c2;
}

In this answer I can see that in c++ static members are unique for each specialization, however, my code seems legit but the static member OnePerType is ignored.

I thought that for each GenTest<> Counter will be printed what happens only when I create objects of type CountedInstances as in the comment. Why is that?

Community
  • 1
  • 1
lord.didger
  • 1,357
  • 1
  • 17
  • 31
  • For each type that your generic class is used, a whole new type will be created. This holds true for C# and for C++. Static variables are shared across the type itself, not across multiple types. List is an entire different type than List. โ€“ user1908061 Jun 16 '13 at 10:29
  • how does it apply to example above? If static member cannot be shared across types then why is initialization of OnePerType outside definition of template class possible? What does this initialization means when it seems to be ignored? โ€“ lord.didger Jun 16 '13 at 11:02

1 Answers1

1

From IBM C++ compilers reference (emphasis mine):

If the compiler implicitly instantiates a class template that contains static members, those static members are not implicitly instantiated. The compiler will instantiate a static member only when the compiler needs the static member's definition.

So to force the compiler to effectively instantiate GenTest<int>::OnePerType and GenTest<double>::OnePerType, you have to reference them somehow. For example you can add (void)&OnePerType; in the constructor (live example: http://ideone.com/CWNr7U).


Edit: Thanks to chris.schuette here's a quote from the C++ Standard (checked for N3337), ยง 14.7.1 (emphasis mine):

1 (...) The implicit instantiation of a class template specialization causes the implicit instantiation of the declarations, but not of the definitions or default arguments, of the class member functions, member classes, scoped member enumerations, static data members and member templates; (...)

8 The implicit instantiation of a class template does not cause any static data members of that class to be implicitly instantiated.

Community
  • 1
  • 1
gx_
  • 4,690
  • 24
  • 31
  • (it works with gcc version 4.7.3) I cannot help but feel that this is somewhat stupid. Don't get me wrong; Your explanation is accurate. The issue itself seems so ridiculously tricky :). โ€“ lord.didger Jun 16 '13 at 11:16