问题描述
我想了解以下类模板的工作原理(摘自),但我不能正确理解:
typename类型>
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
是从它派生的,我不太明白。
更具体地说,当模板参数 无论如何,这是我的测试代码: 输出(): 关于第二个项目符号的标准引文。 C ++ 11§10.2/ 2-6: I'm trying to understand how the following class template works (taken from here), but I couldn't understand it properly: More specifically, I don't understand the purpose of Even more specifically, when template parameter Anyway, this is my test code: Output(ideone): Standard citation regarding the second bullet — C++11 §10.2/2-6: 这篇关于这个has_member类模板如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! Type
定义 operator c $ c>,为什么仅,那么SFINAE被触发,导致第一个
deduce()
函数被忽略, / p>
struct A {}; // SFINAE被触发为A
struct B {void operator()(){}}; //没有为B触发SFINAE
struct C {void operator()(int,int){}}; //没有为C
触发SFINAE c main()
{
std :: cout< std :: boolalpha; //启用true / false而不是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;
}
false
true
true
BaseMixin
有一个运算符()
定义。
c $ c>源于
类型
和 BaseMixin
,因此如果类型
有一个运算符()
然后在上的名称查找Base :: operator()
对于 Base *
,而不是调用
。
deduce
*
助手< void(BaseMixin :: *)(),& U :: operator()> code>只会实例化
& U :: operator()
明确解析为 BaseMixin :: operator()
。
Helper< void(BaseMixin :: *)(),& U :: operator()>
不会实例化,因为类型
有自己的 operator()
查找& U :: operator()
不明确,因此重载
返回类型<$ c $
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
and the presence of operator()
in it. Also, since Base
is derived from it, I don't understand it as well. Type
has defined operator()
, why only then SFINAE is triggered, causing the first deduce()
function to be ignored and the second one is chosen?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;
}
false
true
true
BaseMixin
has an operator()
definition.Base
derives from both Type
and BaseMixin
, so if Type
has an operator()
then name lookup on Base::operator()
will be ambiguous.deduce
is called for Base*
, not Type*
.Helper<void (BaseMixin::*)(), &U::operator()>
will only instantiate if &U::operator()
unambiguously resolves to BaseMixin::operator()
.Helper<void (BaseMixin::*)(), &U::operator()>
does not instantiate, it's because Type
has its own operator()
making name lookup on &U::operator()
ambiguous, and consequently the overload of deduce
returning type yes
is chosen.