本文介绍了这个has_member类模板如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想了解以下类模板的工作原理(摘自),但我不能正确理解:

  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 是从它派生的,我不太明白。



更具体地说,当模板参数 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 $



关于第二个项目符号的标准引文。 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:

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))); 
};

More specifically, I don't understand the purpose of BaseMixin and the presence of operator() in it. Also, since Base is derived from it, I don't understand it as well.

Even more specifically, when template parameter Type has defined operator(), why only then SFINAE is triggered, causing the first deduce() function to be ignored and the second one is chosen?


Anyway, this is my test code:

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;
}

Output(ideone):

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().
  • Conversely, if 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.

Standard citation regarding the second bullet — C++11 §10.2/2-6:

这篇关于这个has_member类模板如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-01 05:46