Reputation: 31
template<class T>
struct is_class_or_union
{
struct twochar { char _[2]; };
template <class U>
static char is_class_or_union_tester(void(U::*)(void));
template <class U>
static twochar is_class_or_union_tester(...);
static const bool value = sizeof(is_class_or_union_tester<T>(0)) == sizeof(char);
};
The above code is from meta_utils.hpp
from boost library.
is_class_or_union_tester
seems to be a static
function returning char
and taking pointer to a member function (that returns void and accepts nothing). There is no function body and it does not seem to be defined anywhere else. I do not understand how it works and above all, I do not understand the purpose of the function.static const bool value = sizeof(is_class_or_union_tester<T>(0)) == sizeof(char);
What is the sizeof
operator applied to? What are they trying to find here ?Upvotes: 1
Views: 141
Reputation: 2985
The technique being employed here is SFINAE (substitution failure is not an error) which is a technique used by the compiler to select a match among possible candidate templates and specifically where an invalid substitution of template parameters is not in itself an error during that matching process. In this case the compiler is attempting to find a match for:
is_class_or_union_tester<T>(0)
It can select between
template <class U>
static char is_class_or_union_tester(void(U::*)(void));
or
template <class U>
static twochar is_class_or_union_tester(...);
If T is a class it will select the first function template because a class can have a member function. If T is a union it will select the second. Recall that sizeof
does not execute the functions and will act only on the return types in the template declarations. You'll see that the return types are different and that makes the comparison against sizeof(char) return the correct value.
Upvotes: 3