2

I'm trying to get the maximum size of any possible instance of my template as a compile time constant. The first thing that came to mind was something like this...

union TestUnion
{
 template<typename T> class MyClass
 {
 public:
  MyClass() { };
  MyClass(T& t) : _t(t) { }

 private:
  T _t;
 };
};

But sizeof(TestUnion) is always equal to 1, but sizeof(MyClass<int>) for instance, correctly returns 4. Anyone have any better ideas?

23L
  • 23
  • 3

3 Answers3

2

There is no such thing as the maximum size of a template class, especially if that class contains an instance of the template argument, as yours does. Consider each of

  template <typename T> class MyClass {
    public:
      MyClass() { };
      MyClass(T& t) : _t(t) { }

    private:
      T _t;
  };

  union TestUnion {
    MyClass<char>;
    MyClass<unsigned char>;
    MyClass<signed char>;
    MyClass<short>;
    // ...
    MyClass<float>;
    MyClass<double>;
    MyClass<char*>;
    MyClass<int*>;
    // ...
    MyClass<void*>;
    MyClass<void (*)(void)>;
    MyClass<std::vector>;
    // ...
    MyClass<int[10]>;
    MyClass<int[100]>;
    MyClass<int[1000]>;
    MyClass<int[10000]>;
    MyClass<int[100000]>;
  };

and so on... Or equally excitingly, insert

    MyClass< MyClass< MyClass< ... < XImage > ... > > >

(which is admittedly not guaranteed to work at greater than the promised maximum nested template instantiation depth (17 now, 1024 soon)).

So, clearly there's no theoretical maximum. If you have a universe of types in mind that will actually be template parameters to MyClass<>, then it might be do-able.

EDIT -- replaced < with &lt; so the template argument wouldn't be hidden by the SO parser.

Eric Towers
  • 4,175
  • 1
  • 15
  • 17
1

You are getting the size of a union that has no members. Declaring a template within a union scope doesn't declare any union members. In C++ (and also I believe C) it is guaranteed that all class or union types occupy at least 1 byte of space. So that's why the size is 1.

There is no way to get the maximum possible size, and that's because a template class can contain an instance of an arbitrary type that's not known until the template is instantiated. This type could be of arbitrary size. I will illustrate what I mean in an edit to this post within an hour or two.

Omnifarious
  • 54,333
  • 19
  • 131
  • 194
  • Right. I understand the issue here. So if I instantiate the template inside of a union, that works. Unfortunately, I'm not sure if that will work for me. – 23L Oct 24 '10 at 04:02
  • @23L - Well, someone else posted an excellent example, so I won't bother with mine. :-) – Omnifarious Oct 24 '10 at 04:31
0

I'm not an expert when it comes to sizing C++ classes... I'm sure there is a better way. Assuming you want just a potential maximum size for all the instances you plan on using, here is a likely hacky way:

const foo = (sizeof(MyClass) > sizeof(MyClass) ? (sizeof(MyClass) : sizeof(MyClass)

Then repeat to no-end nesting them as needed.

Wes Hardaker
  • 21,735
  • 2
  • 38
  • 69