“is_base_of”的替代实施方式(检查基础/派生关系) [英] Alternate implementation of "is_base_of" (checking base/derived relationship)

查看:155
本文介绍了“is_base_of”的替代实施方式(检查基础/派生关系)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在讨论如何在boost中实现 is_base_of (它决定给定的是否是编译时另一个的基础]。

I was going through a nice question for how is_base_of is implemented in boost (which decides if a given class is a base of another class at compile time].

第一次看到这样的代码,我惊讶于如何使事情变得如此美妙!但是,很多步骤让我很难理解(阅读完所有答案后)。所以,我我想知道如果这个功能可以替代实现。我试过以下:

Seeing such code for the 1st time, I got amazed that how things can be made to work so nicely! However, many steps I got confused to understand (after reading all the answers). So, I was wondering that if this functionality can be implemented alternatively. I tried following:

template<class B, class D>
struct is_base_of
{
  template<typename T> struct dummy {};
  struct Child : D, dummy<int> {};

  static B* Check (B*);
  template<class T> static char Check (dummy<T>*);

  static const bool value = (sizeof(Check((Child*)0)) == sizeof(B*));
};

按预期工作正常一般情况。

It works fine as per expectation for the general case.

唯一的问题是 private / protected 继承。它会选择预期的功能,但也会显示错误: - 是... 的无法访问的基础。我很感激,如果有人可以建议代码中缺少任何修改来解决这个问题(如果不是功能明智,那么至少要摆脱错误信息)。

The only problem is for private/protected inheritance. It goes and choose the expected function, but also shows error as:- is an inaccessible base of .... I would appreciate if someone can suggest any little modification missing to the code to solve this problem (If not the functionality wise then at least to get rid of the error message).

[注意:我假设 char B * 将始终具有不同的大小并避免典型的类型转换是'和'否']

[Note: I have assume that char and B* will always be of different sizes and avoided typecasting of typical 'yes' and 'no']

推荐答案

我认为链接解决方案的关键部分是无论最终结果如何be(相关或不相关) - 所选择的转换序列实际上不包括要测试的继承。编译器在选择适当版本的 check 函数时会考虑它。但是每次最后选择的路径都不会实际使用它。

I think the key part in the linked solution was that no matter what the end result would be (related or unrelated) - the chosen conversion sequence wouldn't actually include the inheritance that is tested for. Compiler is taking it into consideration in the process of selecting the appropriate version of the check function. However each time in the end the path selected wouldn't actually use it.

在您的代码中,如果类是相关的,则调用检查确实利用从 Child * 转换为 B * 的继承。而且 - 我害怕无法轻易修复,因为您提出的方法非常不同。

In your code however if the classes are related, the call to check indeed does make use of the inheritence converting from Child* to B*. And this - I'm afraid cannot be fixed easily as the approach that you presented is very different.

如果相关

您的解决方案

儿童 D 因此也是 B 。因此,存在从 Child * B * 的转换。所以 Check 的第一个版本是可行的。 Check 的第二个版本是可行的,而 Child 也是 dummy< int> 因此 Child * dummy< int> * 。选择第一个版本,因为这不涉及模板参数专业化。

Child is D therefore is also B. Therefore there exists conversion from Child* to B*. So the first version of Check is viable. The second version of Check is viable as well as Child is also dummy<int> and therefore Child* is dummy<int>*. The first version is selected as this doesn't involve template parameter specialization.

链接的解决方案

对于第一个版本的检查主机< B,D> 通过用户定义的转换进行转换到 D * 。转换结果类型与函数参数完全匹配。这里没有使用继承。

For the first version of check: Host<B, D> is converted via user defined conversion to D*. The conversion result type exactly matches the function argument. No inheritance is used here.

对于的第二个版本,检查 Host< B ,D> 再次通过用户定义的转换转换为 D * 。转换结果类型为 D * ,可以进一步转换为 B * 以匹配函数参数。这里确实使用了继承。

For the second version of check: Host<B, D> is converted again via user defined conversion to D*. The conversion result type is D* which can be further converted to B* in order to match the function argument. Inheritance is indeed used here.

但是最后编译器会选择第一个版本,因为它注意到转换结果更符合 check <的参数/ code>。

However in the end compiler chooses the first version as it was noted the conversion result better matches the argument of check.

如果不相关

您的解决方案

孩子不是 B 因此第一个版本检查不是一个选项。第二个版本是可行的,因为 Child 仍然是 dummy< int> 因此可以专门从虚设< T> 。因为只有一个选项,所以选择很简单。

Child isn't B therefore the first version of Check is not an option. Second version is viable as the Child is still dummy<int> therefore can be specialized from dummy<T>. As there is only one option the choice is trivial.

链接的解决方案

对于的第一个版本,请检查主机< B,D> 转换为 D * 通过用户定义的转换。

For the first version of check: Host<B, D> is converted to D* via user defined conversion.

对于的第二个版本,请检查主机< B,D> 转换为 const主机< B,D> 然后转换为 B * 通过用户定义的转换。

For the second version of check: Host<B, D> is converted to const Host<B, D> and then to B* via user defined conversion.

如果不是因为只有一个版本的检查函数有模板参数。

The paths would be incomparable if it were not for the fact that only one version of check function has template arguments.

正如您所看到的,这两种方法有很大不同。

As you can see the two approaches are significantly different.

这篇关于“is_base_of”的替代实施方式(检查基础/派生关系)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆