Я пытаюсь понять, как работает следующий шаблон класса (взято из здесь), но я не мог понять это правильно:
template <typename Type>
class has_member
{
class yes { char m;};
class no { yes m[2];};
struct BaseMixin
{
void operator()(){}
};
struct Base : public Type, public BaseMixin {};
template <typename T, T t> class Helper{};
template <typename U>
static no deduce(U*, Helper<void (BaseMixin::*)(), &U::operator()>* = 0);
static yes deduce(...);
public:
static const bool result = sizeof(yes) == sizeof(deduce((Base*)(0)));
};
Точнее, я не понимаю назначение BaseMixin
и наличие в нем operator()
. Кроме того, поскольку Base
происходит от него, я тоже этого не понимаю.
Более конкретно, когда параметр шаблона Type
определил operator()
, почему только запускается SFINAE, в результате чего первая функция deduce()
игнорируется и выбирается вторая?
Во всяком случае, это мой тестовый код:
struct A{}; //SFINAE is triggered for A
struct B{ void operator()(){} }; //SFINAE is not triggered for B
struct C{ void operator()(int,int){} }; //SFINAE is not triggered for C
int main()
{
std::cout << std::boolalpha; //enable true/false instead of 1/0!
std::cout << has_member<A>::result << std::endl;
std::cout << has_member<B>::result << std::endl;
std::cout << has_member<C>::result << std::endl;
}
Вывод(ideone):
false
true
true