views:

178

answers:

2

Hi guys, referring to yesterday's post, this woke me up this morning. Why does this actually work? As long as the function test is concerned, this function has no body so how can it perform anything? I want to know why and how this works? I'm REALLY interested to see your answers.

template<typename T> 
class IsClassT { 
  private: 
    typedef char One; 
    typedef struct { char a[2]; } Two; 
    template<typename C> static One test(int C::*); //NO BODY HERE
    template<typename C> static Two test(…); //NOR HERE
  public: 
    enum { Yes = sizeof(IsClassT<T>::template test<T>(0)) == sizeof(One) }; 
    enum { No = !Yes }; 
}; 

Thanks in advance with help to understand this very interesting phenomenon.

+5  A: 

I assume you are refering to the Yes enum? IsClassT<T>::test<T>(0)? sizeof does not actually evaluate its arguments. That's why code like the following is legal, even though you might expect it to bail out on you:

int* p = 0;
int sizeof_int = sizeof(*p); //oops, p is 0 :(
Dennis Zickefoose
What I'm really interested in is why even though test has no body I get no error for this?
There is nothing we can do
Because the return type is known at compile time without the body. It's simply a `char` or `char[2]`. That is all the compiler needs, and it's sanctioned by the standard. To be clear, `sizeof` applies to the return value of the function (not, e.g., the code size of the function), and to compute that you only need to know the type, not have an actual object of that type.
Ari
+8  A: 
  1. You can not get compiler error because test-function declaration exists.

  2. You can not get linker error because you do not call test-function.

C++ Standart ISO/IEC 14882:2003(E)

5.3.3 Sizeof

The sizeof operator yields the number of bytes in the object representation of its operand. The operand is either an expression, which is not evaluated, or a parenthesized type-id. The sizeof operator shall not ...

...

Alexey Malistov