Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why this works (Templates, SFINAE). C++

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.

like image 780
There is nothing we can do Avatar asked Mar 17 '10 10:03

There is nothing we can do


People also ask

What is the main problem with templates?

There are two main reasons why people dislike templates: They're confusing. They can lead to long compilation times.

What is SFINAE used for?

Substitution failure is not an error (SFINAE) refers to a situation in C++ where an invalid substitution of template parameters is not in itself an error. David Vandevoorde first introduced the acronym SFINAE to describe related programming techniques.

Will concepts replace SFINAE?

So the simple answer is YES.

What is Typename C++?

" typename " is a keyword in the C++ programming language used when writing templates. It is used for specifying that a dependent name in a template definition or declaration is a type.


2 Answers

  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 ...

...

like image 143
Alexey Malistov Avatar answered Sep 21 '22 23:09

Alexey Malistov


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 :(
like image 29
Dennis Zickefoose Avatar answered Sep 21 '22 23:09

Dennis Zickefoose