is_base_of

来源:互联网 发布:matlab 2014b mac 360 编辑:程序博客网 时间:2024/04/28 16:21

`is_base_of'如何工作?(How does `is_base_of` work?)

 C/C++IT屋 2016/10/11 20:27:02 
百度翻译此文   有道翻译此文
问 题

How does the following code work?

typedef char (&yes)[1];typedef char (&no)[2];template <typename B, typename D>struct Host{  operator B*() const;  operator D*();};template <typename B, typename D>struct is_base_of{  template <typename T>   static yes check(D*, T);  static no check(B*, int);  static const bool value = sizeof(check(Host<B,D>(), int())) == sizeof(yes);};//Test sampleclass Base {};class Derived : private Base {};//Exspression is true.int test[is_base_of<Base,Derived>::value && !is_base_of<Derived,Base>::value];
  1. Note that B is private base. How does this work?

  2. Note that operator B*() is const. Why is it important?

  3. Why is template<typename T> static yes check(D*, T); better than static yes check(B*, int); ?

Note: It is reduced version (macros are removed) of boost::is_base_of. And this works on wide range of compilers.

解决方案

If they are related

Let's for a moment assume that B is actually a base of D. Then for the call to check, both versions are viable because Host can be converted to D* and B*. It's a user defined conversion sequence as described by 13.3.3.1.2 from Host<B, D> to D* and B* respectively. For finding conversion functions that can convert the class, the following candidate functions are synthesized for the first check function according to 13.3.1.5/1

D* (Host<B, D>&)

The first conversion function isn't a candidate, because B* can't be converted to D*.

For the second function, the following candidates exist:

B* (Host<B, D> const&)D* (Host<B, D>&)

Those are the two conversion function candidates that take the host object. The first takes it by const reference, and the second doesn't. Thus the second is a better match for the non-const *this object (the implied object argument) by 13.3.3.2/3b1sb4 and is used to convert to B* for the second check function.

If you would remove the const, we would have the following candidates

B* (Host<B, D>&)D* (Host<B, D>&)

This would mean that we can't select by constness anymore. In an ordinary overload resolution scenario, the call would now be ambiguous because normally the return type won't participate in overload resolution. For conversion functions, however, there is a backdoor. If two conversion functions are equally good, then the return type of them decides who is best according to 13.3.3/1. Thus, if you would remove the const, then the first would be taken, because B* converts better to B* than D* to B*.

Now what user defined conversion sequence is better? The one for the second or the first check function? The rule is that user defined conversion sequences can only be compared if they use the same conversion function or constructor according to 13.3.3.2/3b2. This is exactly the case here: Both use the second conversion function. Notice that thus the const is important because it forces the compiler to take the second conversion function.

Since we can compare them - which one is better? The rule is that the better conversion from the return type of the conversion function to the destination type wins (again by 13.3.3.2/3b2). In this case, D* converts better to D* than to B*. Thus the first function is selected and we recognize the inheritance!

Notice that since we never needed to actually convert to a base class, we can thereby recognize private inheritance because whether we can convert from a D* to a B* isn't dependent on the form of inheritance according to 4.10/3

If they are not related

Now let's assume they are not related by inheritance. Thus for the first function we have the following candidates

D* (Host<B, D>&) 

And for the second we now have another set

B* (Host<B, D> const&)

Since we cannot convert D* to B* if we haven't got a inheritance relationship, we now have no common conversion function among the two user defined conversion sequences! Thus, we would be ambiguous if not for the fact that the first function is a template. Templates are second choice when there is a non-template function that is equally good according to 13.3.3/1. Thus, we select the non-template function (second one) and we recognize that there is no inheritance between B and D!

本文地址:IT屋 » How does `is_base_of` work?

问 题

以下代码如何工作?



  typedef char(& yes)[1] 
typedef char(& no)[2];

template< typename B,typename D>
struct Host
{
运算符B *()const;
operator D *();
};

template< typename B,typename D>
struct is_base_of
{
template< typename T>
static yes check(D *,T);
静态无检查(B *,int);

static const bool value = sizeof(check(Host< B,D>(),int()))== sizeof
};

//测试样例
class Base {};
class Derived:private Base {};

//暴露是真的。
int test [is_base_of< Base,Derived> :: value&& !is_base_of< Derived,Base> :: value];




  1. 注意 code>是私人基地。这个怎么用?


  2. 请注意,运算符B *()是const。为什么很重要?


  3. 为什么是 template< typename T&静态是检查(D *,T); 好于 static yes check(B *,int); ?




注意:<$ c $的缩减版c> boost :: is_base_of 。


解决方案

如果它们是相关的



让我们暂且假设 B 实际上是 D 的基础。然后对于 check 的调用,两个版本都是可行的,因为 Host 可以转换为 D * B * 。它是由 13.3.3.1.2 从主机< B,D> 到 D * 和 B * 。为了找到可以转换该类的转换函数,根据 13.3.1.5/1



  D *(主机< B,D&&;)


第一个转换函数不是候选项,因为 B * 到 D * 。



对于第二个函数,存在以下候选项:



  B *(Host< B,D> const&)
D *(Host< B,D &&)

b $ b

这些是接受主机对象的两个转换函数候选。第一个用const引用,第二个不用。因此,第二个是由 13.3更好地匹配非const * this 对象( implied object argument )。 3.2 / 3b1sb4 ,用于为第二个检查函数转换 B *



如果您删除常量,我们将有以下候选人



  B *(Host< B,D&)
D *(Host< B,D&)
pre>

这意味着我们不能选择constness了。在普通的重载解决方案中,该调用现在是不明确的,因为通常返回类型将不参与重载分辨率。然而,对于转换函数,有一个后门。如果两个转换函数同样好,那么它们的返回类型根据 13.3.3 / 1 决定谁是最好的。因此,如果你删除const,那么第一个将被采取,因为 B * 更好地转换为 B * D * 至 B * 。



用户定义的转换顺序更好?一个用于第二个还是第一个检查功能?规则是用户定义的转换序列只能根据 13.3.3.2/3b2 使用相同的转换函数或构造函数进行比较。这正是这种情况:两者都使用第二个转换函数。请注意,因此 const 很重要,因为它强制编译器采用第二个转换函数。



因为我们可以比较它们 - 哪一个更好?规则是,从转换函数的返回类型到目标类型的转换更好(再次通过 13.3.3.2/3b2 )。在这种情况下, D * 更好地转换为 D * 比 B * 。因此,选择第一个函数,并识别继承!



请注意,由于我们从来不需要实际转换为基类,因此我们可以从而识别私人继承,因为我们是否可以从 D * 转换为 B * 根据 4.10 / 3



如果它们不相关,则不依赖于继承的形式



现在让我们假设它们没有继承关系。因此,对于第一个函数,我们有以下候选



  D *(Host< B,D&  


而对于第二个,我们现在有另一个



  B *(Host< B,D> const&)


如果我们没有继承关系,我们不能将 D * 转换为 B * 函数在两个用户定义的转换序列之间!因此,如果不是因为第一个函数是模板,我们会模糊。当有一个非模板函数根据 13.3.3 / 1 同样好的时候,模板是第二选择。因此,我们选择非模板函数(第二个),并且我们认识到 B 和 D !


本文地址:IT屋 » `is_base_of'如何工作?

百度翻译此文   有道翻译此文
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 被棘冠海星刺到怎么办 家里突然水压小怎么办 自来水出水量小怎么办 开水龙头水管响怎么办? 海里游泳遇到暗流怎么办 网站运营权出问题怎么办 在澳门超期出关怎么办 妹妹初中毕业谈恋爱怎么办 原告的证据造假怎么办 慕课考试不及格怎么办 大学高数不及格怎么办 对方拒绝司法调解怎么办? cas授权已过期怎么办 英法巡航南海中国怎么办 wps文件不能改怎么办 wps不能删除内容怎么办 word文件被锁定怎么办 word批注不显示怎么办 wps怎么办把修订取消 审阅密码忘了怎么办 psv关机后怎么办刷 被螃蟹扎了怎么办 被海鲜划伤出血怎么办 海域使用证缴纳金没交怎么办 海峡中线 金门海域怎么办 对工作失去热情怎么办 取款机多出钱怎么办 风扇声音很响怎么办 稳压器输出没电怎么办 稳压器不稳10压怎么办 dnf凯蒂不见了怎么办 马桶里掉进塑料瓶盖怎么办 塑料瓶子盖子打不开怎么办 按压瓶盖坏了怎么办 瓶盖拧错位了怎么办 红酒盖子开不了怎么办 胶盖罐头打不开怎么办 玻璃瓶的塑料盖打不开怎么办 香水按压不出来怎么办 电高压锅盖子打不开怎么办 杯子螺口错位怎么办