- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在思考一个关于如何 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 ...
。如果有人可以建议对代码进行任何小的修改以解决此问题,我将不胜感激(如果不是明智的功能,那么至少要摆脱错误消息)。
[注意:我假设 char
和 B*
将始终具有不同的大小并避免典型的"is"和“否”的类型转换]
最佳答案
我认为链接解决方案中的关键部分是无论最终结果是什么(相关或不相关)——所选的转换序列实际上不会包括测试的继承。编译器在选择 check
的适当版本的过程中将其考虑在内功能。然而,每次最终选择的路径都不会实际使用它。
但是在您的代码中,如果类是相关的,则调用 check
确实确实利用了从 Child*
转换而来的继承至 B*
.而这 - 恐怕无法轻易解决,因为您提出的方法非常不同。
如果相关
您的解决方案
Child
是D
因此也是B
.因此存在从 Child*
的转换至 B*
.所以第一个版本Check
是可行的。第二版Check
和Child
一样可行也是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/
我试图断言模板参数将派生自某个基类。但是基类是通用的,在断言的上下文中,任何特化类型之间都没有区别。我如何断言模板参数派生自任何专用类型的泛型? 我试着把它写成 base_generic: templ
给定代码: template struct Cat { ... }; template struct Bengal : Cat { ... }; template struct Persian : C
以下代码是如何工作的? typedef char (&yes)[1];typedef char (&no)[2];template <typename B, typ
我正在研究共享指针的实现。 (使用C++ 17,以防万一) 唯一的问题是转换构造函数。我希望能够将smart_ptr静态转换为基本类型的smart_ptr。 template inline smart
我有这样的层次结构: namespace MyService{ class IBase { public: virtual ~IBase(){} protected: IPointer
只是想知道为什么我不能像下面这样在 C++ 模板参数中使用 is_base_of: #include #include using namespace std; struct base { };
有没有办法判断一个基类是不是虚基类? std::is_base_of 将标识一个基类,但我正在寻找类似 std::is_virtual_base_of 的东西来标识一个虚拟基类。 这是出于 SFINA
有没有办法测试std::is_base_of什么时候A是模板类吗? template class A {}; template class B : public A {}; 我想静态测试类似 st
我正在尝试做一个结构类似于此的程序: #include template class Test {}; template class Test::value>::type> { public:
是否有可能静态断言作为模板参数提供的类型是否实现了参数包中列出的所有类型,即。参数包感知 std::is_base_of()? template class CommonBase { sta
使用下面的代码,我收到编译器投诉,称前两个模板之间对 get_code 的调用不明确。我如何编写代码来检测基类,同时还提供专门的形式?例如,如果稍后我有 class C : A {},它也应该返回 A
1. template std::true_type is_base_of_test_func( Base* ); 2. template std::false_type is_base_of
有没有办法测试std::is_base_of当A是模板类吗? template class A {}; template class B : public A {}; 我想静态测试 std::is
我对以下情况感到有点困惑,我在 is_base_of 上启用了特化。 is_base_of 需要被检查的类型的完整定义是可用的。但是,正在专门化的类型被用作正在检查的基类类型的成员 - 因此两者都需要
我遇到了模板问题: 我有两个构造函数和方法:.cpp: Cell::Cell(sf::Vector2i& uPos, sf::Vector2f& cellDimensions, std::string
我想创建一个库:- 用户通过 addCallback(Callback* callback) 添加回调(通常在第一个时间步) 之后,通常在不同的.cpp , 每当用户调用 actor() :- 如果B
我正在思考一个关于如何 is_base_of 的好问题在 boost 中实现(它决定一个给定的 class 在编译时是否是另一个 class 的基础)。 第一次看到这样的代码,我很惊讶怎么能把事情做得
我完全明白为什么这个不能工作了: class Base {}; class A; static_assert(std::is_base_of::value, ""); 因为没有关于“类层次结构”的信息
根据 C++11 标准 std::is_base_of如果 D 是从 B 派生的,或者两者是同一个非 union 类,则必须返回 true。但是在 VC++ 2010 STL 实现模板中,如果类型 B
为简洁起见,这是简化的层次结构: class IBase { public: virtual ~IBase() = 0 { }; }; // eo IBase class IDerived
我是一名优秀的程序员,十分优秀!