views:

484

answers:

3

I hit a snag today... I wanted to define a small templated helper class:

template<class T>
CMyClass
{
public : 
    CMyClass() { size_t iSize = sizeof(T); } // Allowed. 
    size_t GetElementSize() const { return sizeof(T); } // C2027.
};

and of course, it wouldn't compile (C2027). My question was, is it possible to get the size of the type? The reason I need this is that the type the object is constructed with could be a number of differently-defined structures, and so I need to get the size of the structure used, at run time.

Through a quick bit of experimentation, because I'm stubborn, it seems that I can use sizeof(T) in the ctor, but not in the non-ctor function - so my question now is... why?!

+1  A: 

Not sure what the proper answer to your question is, but it seems you can work around it by just making iSize a member and have GetElementSize() return it instead of calling sizeof again.

jeffamaphone
I did discover this in the end, although I have also found that when I try and extract the relevant code to a small example, it no longer fails.
JTeagle
+2  A: 

Seems to work fine here, what's the message of C2027? And what compiler are you using?

Kim Gräsman
I'm using VS2005, patched - I believe that is named VC8 or VC8.1?The full error text is: myclass.h(170) : error C2027: use of undefined type 'T'see declaration of 'T'while compiling class template member function 'size_t CMyClass<T>::GetElementSize(void) const'with[T=T]see reference to class template instantiation CMyClass<T>' being compiledwith[T=T]and it was being instantiated with CMyClass<SOME_STRUCT_DEF> ElementStore ; where SOME_STRUCT_DEF contains three floats and a DWORD + its own ctor.
JTeagle
Yikes, sorry about the loss of formatting there.
JTeagle
Actually, I must withdraw thw question. It doesn't seem to happen in all cases - particularly, when I try to extract the bare bones and create a compilable test sample, it's not happening. Grrr!
JTeagle
+2  A: 

It can have different reasons. Consider this code:

// file foo.h
class X;

template<class T>
class CMyClass
{
public : 
    CMyClass() { size_t iSize = sizeof(T); } // Allowed. 
    size_t GetElementSize() const { return sizeof(T); } // C2027.
};

struct Class {
  Class(); // definition of it in the cpp file, where "X" is fully defined
  void callit() { cm.GetElementSize(); } // instantiated here!
  CMyClass<X> cm;
};

At the time the constructor is instantiated (in the ".cpp" file), T is a completely defined type. But at the time GetElementSize is instantiated (in the ".h" file), X is not yet completely defined.

Johannes Schaub - litb
@litb: I think that error would require two-phase lookup, while "C2027" hints at VC -- which unfortunately doesn't implement this.
sbi
I'm not sure about anything with VC. That compiler is too much broken for me to assume anything about it :)
Johannes Schaub - litb
@sbi: There's no 2-phase lookup here. 2-phase lookup is the term used to describe the lookup that takes place in the scope of the argument types, for a function call that involved dependent arguments.
Richard Corden
@litb: I think based on the error message in the comment to the answer by "Kim Grasman" that you've supplied the correct answer here.
Richard Corden