SFINAE与is_base_of

SFINAE:即Substitution Failure Is Not an Error!可以理解为匹配失败不是错误,更严格的说应该是参数匹配失败不是一个编译时错误。

C++函数匹配的顺序遵循的原则是按照以下顺序

1.寻找参数的完美匹配函数,找到则使用

2.寻找模板函数,若实例化后的函数能够匹配则使用

3.通过默认类型转换后的参数去匹配,找到则使用

4.匹配失败,提示函数匹配错误

下面通过实现is_base_of来说明SFINAE的一般用法,来自于

http://stackoverflow.com/questions/2910979/how-does-is-base-of-work

1.定义

1 namespace blog {
 2     template <class D, class B>
 3     struct ConversionHelper
 4     {
 5         struct Host
 6         {
 7             operator B() const;
 8             operator D();
 9         };
10         typedef char(&yes)[1];
11         typedef char(&no)[2];
12         template <typename T>
13         static yes Test(D, T);
14         static no Test(B, int);
15     };
16 
17     template <class D, class B>
18     struct Conversion
19     {
20         typedef ConversionHelper<D, B> H;
21 22         typedef typename H::Host Host;
23         enum { exists = sizeof(typename H::yes) == sizeof(H::Test(Host(), int())) };
24         enum { exists2Way = exists && Conversion<B, DD>::exists };
25         enum { sameType = false };
26     };
27 
28     template <class D>
29     struct Conversion<D, D>
30     {
31         enum { exists = 1, exists2Way = 1, sameType = 1 };
32     };
33 
34     template <class D>
35     struct Conversion<void, D>
36     {
37         enum { exists = 1, exists2Way = 0, sameType = 0 };
38     };
39 
40     template <class D>
41     struct Conversion<D, void>
42     {
43         enum { exists = 1, exists2Way = 0, sameType = 0 };
44     };
45 
46     template <>
47     struct Conversion<void, void>
48     {
49     public:
50         enum { exists = 1, exists2Way = 1, sameType = 1 };
51     };
52 
53     template<typename B, typename D>
54     struct is_base_of {
55         enum {
56             value = (me::Conversion<const D*, const B*>::exists && !me::Conversion<const B*, const void>::sameType)
57         };
58     };
59 }
1 template<typename B,typename D>
2 struct is_base_of {
3     enum {
4         value = (Conversion<const D*, const B*>::exists && !Conversion<const B*, const void>::sameType)
5     };
6 };

2.使用

1 struct A{};
2 struct B{};
3 struct C : public B
4 {
5     static_assert(blog::is_base_of<C, B>::value, "B is not the base of C");
6     //static_assert(std::is_base_of<C, B>::value, "B is not the base of C");
7 };

在上面代码中,由于std::is_base_of在struct C结构体中,C还没有定义完整,因此会出错。

而blog::is_base_of使用的是指针转换,当转换存在时,ConversionHelper::Test(D,T)
原文链接: https://www.cnblogs.com/goooon/p/5644326.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/236459

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月13日 下午5:02
下一篇 2023年2月13日 下午5:03

相关推荐