gpt4 book ai didi

c++ - "is_base_of"的替代实现(检查基础/派生关系)

转载 作者:太空狗 更新时间:2023-10-29 21:50:37 31 4
gpt4 key购买 nike

我正在思考一个关于如何 is_base_of 的好问题在 boost 中实现(它决定一个给定的 class 在编译时是否是另一个 class 的基础)。

第一次看到这样的代码,我很惊讶怎么能把事情做得这么好!然而,许多步骤让我感到困惑(在阅读了所有答案之后)。所以,我想知道是否可以替代地实现此功能。我试过以下:

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

按照一般情况的预期,它工作正常。

唯一的问题是 private/protected 继承。它会选择预期的功能,但也会显示错误:- is an accessible base of ...。如果有人可以建议对代码进行任何小的修改以解决此问题,我将不胜感激(如果不是明智的功能,那么至少要摆脱错误消息)。

[注意:我假设 charB* 将始终具有不同的大小并避免典型的"is"和“否”的类型转换]

最佳答案

我认为链接解决方案中的关键部分是无论最终结果是什么(相关或不相关)——所选的转换序列实际上不会包括测试的继承。编译器在选择 check 的适当版本的过程中将其考虑在内功能。然而,每次最终选择的路径都不会实际使用它。

但是在您的代码中,如果类是相关的,则调用 check确实确实利用了从 Child* 转换而来的继承至 B* .而这 - 恐怕无法轻易解决,因为您提出的方法非常不同。

如果相关

您的解决方案

ChildD因此也是B .因此存在从 Child* 的转换至 B* .所以第一个版本Check是可行的。第二版CheckChild一样可行也是dummy<int>因此 Child*dummy<int>* .选择第一个版本是因为它不涉及模板参数特化。

链接的解决方案

第一个版本check : Host<B, D>通过用户定义的转换转换为 D* .转换结果类型与函数参数完全匹配。这里没有使用继承。

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

但是最终编译器选择了第一个版本,因为转换结果更好地匹配了 check 的参数.

如果无关

您的解决方案

Child不是 B因此第一个版本Check不是一个选项。第二个版本是可行的 Child还是dummy<int>因此可以从 dummy<T> 专门化.由于只有一个选项,因此选择很简单。

链接的解决方案

第一个版本check : Host<B, D>转换为 D*通过用户定义的转换。

对于 check 的第二个版本: Host<B, D>转换为 const Host<B, D>然后到B*通过用户定义的转换。

如果不是因为check只有一个版本,路径将是无与伦比的函数有模板参数。

如您所见,这两种方法有很大不同。

关于c++ - "is_base_of"的替代实现(检查基础/派生关系),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5770467/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com