Lea*_*Cpp 4 c++ templates c++11
下面是我遇到的代码,它实际上是std::is_base_of
在C++ 11或C++中完成的boost::is_base_of
.
辅助函数下面也是这样的:
template<typename D, typename B>
class IsDerivedFromHelper
{
class No { };
class Yes { No no[3]; };
static Yes Test( B* );
static No Test( ... );
public:
enum { Is = sizeof(Test(static_cast<D*>(0))) == sizeof(Yes) };
};
template <class C, class P>
bool IsDerivedFrom() {
return IsDerivedFromHelper<C, P>::Is;
}
Run Code Online (Sandbox Code Playgroud)
有人能解释一下enum的Is
作用吗?
什么是静态Yes
Test
和静态No
Test
?它们是功能调用吗?
Ric*_*ges 13
class No { };
- 定义一个类,它将具有未定义的大小,该大小不会为零(由标准强制规定)
class Yes { No no[3]; };
- 定义另一个类,Yes
它至少是a的3倍No
.所以他们保证不同的尺寸.
static Yes Test( B* );
- 声明一个返回a的函数Yes
,但不给它一个定义(我们不需要一个).它将匹配任何指向派生自的对象的指针参数B
.
static No Test( ... );
- 声明一个返回a的函数No
(更小,记得?).如果不能满足更具体的一个(上面),则选择过载.它接受任何参数(但如果参数派生自优先选择,则优先选择其他版本B
).
sizeof(Test(static_cast<D*>(0)))
推断将Test
指针传递给a时返回的对象的大小D
.如果D
是派生的B
,那将是一个Yes
,否则它将是一个No
.
因为'call'是在非推导的上下文中进行的,所以它不被评估(调用),只是被选中并且被推导出返回类型.
其余的可能是不言自明的.事实证明它不是:)
所以这一切都放在这里:
enum { Is = sizeof(Test(static_cast<D*>(0))) == sizeof(Yes) };
简而言之,这就是说:
"声明一个叫做常数Is
,这将是true
,如果在调用测试用的结果D*
是,恰好是大小为同一个类型Yes
,而且这将是false
,如果调用的结果恰好是一个类型,是不同大小.由于上面有两个重载,当D是B或从它派生的任何东西时,Test(D*)
会选择Yes
返回a 的版本,这Yes
显然与a的大小相同Yes
.如果没有选择此过载,则更宽松(但是优先级较低)一个将是.那一个返回a No
,显然不会与a Yes
(根据定义)的大小相同."
为什么Test(...)
"优先级低于" Test(B*)
(在重载决策方面)?因为它只是.标准定义它.
最后:
template <class C, class P>
bool IsDerivedFrom() {
return IsDerivedFromHelper<C, P>::Is;
}
Run Code Online (Sandbox Code Playgroud)
这将创建一个函数,它将为任何两个类类型返回上述测试的结果,C
并且P
.如果P
从a派生,它将返回true,否则返回C
false.
归档时间: |
|
查看次数: |
1021 次 |
最近记录: |