专栏首页进击的程序猿C++奇淫巧技之SFINAE

C++奇淫巧技之SFINAE

SFINAE 技术,即匹配失败不是错误,英文Substitution Failure Is Not An Error,其作用是当我们在进行模板特化的时候,会去选择那个正确的模板,避免失败

看个具体的例子:

long multiply(int i, int j) { return i * j; }

template <class T>
typename T::multiplication_result multiply(T t1, T t2)
{
    return t1 * t2;
}
int main(void)
{
    multiply(4,5);
}

当我们编译的时候,会去匹配模板 multiply,但是由于我们不知道multiplication_result,根据 Substitution Failure Is Not An Error ,于是我们就去选择函数 multiply

这种技术在代码中的一个大的用途就是在编译时期来确定某个 type 是否具有我们需要的性质,看代码

template <class T>
struct is_pointer
{
    template <class U>
    static char is_ptr(U *);

    template <class X, class Y>
    static char is_ptr(Y X::*);

    template <class U>
    static char is_ptr(U (*)());

    static double is_ptr(...);

    static T t;
    enum { value = sizeof(is_ptr(t)) == sizeof(char) };
};

struct Foo {
    int bar;
};

void testTypeCheck() {
    typedef int * IntPtr;
    typedef int Foo::* FooMemberPtr;
    typedef int (*FuncPtr)();

    printf("%d\n",is_pointer<IntPtr>::value);        // prints 1
    printf("%d\n",is_pointer<FooMemberPtr>::value);  // prints 1
    printf("%d\n",is_pointer<FuncPtr>::value);       // prints 1
}

通过定义4个重载的 is_ptr函数,3个是接受不同的指针参数,另一个则包括了其他的所有参数, IntPtr 是一个变量指针 FooMemberPtr 是一个成员属性指针 FuncPtr 是一个函数指针

接着我们来看下 muduo 库中的一段代码:

template<typename T>
struct has_no_destroy {
    template<typename C>
    static char test(decltype(&C::no_destroy));


    template<typename C>
    static int32_t test(...);

    const static bool value = sizeof(test<T>(0)) == 1;
};
// 其作用就是用来判断是否有 no_destroy 函数

struct A {

};

struct B {
    void no_destroy(){}
};
struct C {
    int no_destroy;
};

struct D : B {

};

void testNoDestroy() {
    printf("%d\n",has_no_destroy<A>::value);
    printf("%d\n",has_no_destroy<B>::value);
    printf("%d\n",has_no_destroy<C>::value);
    printf("%d\n",has_no_destroy<D>::value);
}

其作用主要是判断是否有no_destroy,并且在继承上也成立,但是继承在不同的gcc版本上不一定成立,具体可以看:http://stackoverflow.com/questions/1966362/sfinae-to-check-for-inherited-member-functions

code地址:https://github.com/zhuanxuhit/happy-code/tree/master/src/idioms

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Linearizability versus Serializability

    原文 Linearizability和Serializability是在数据库和分布式系统中重要的两个概念,而且比较容易混淆,这篇文章试着对两个概念的不同进行...

    zhuanxu
  • 图数据库奥秘初探

    主要参考书籍:graph database 近期工作中要做一些图谱的应用,于是这几天就调研了下图数据库,最后就有了本文。ps:本人第一次做图谱相关的应用,具体...

    zhuanxu
  • 神经网络基础知识

    我们可以调整参数/权重W,使得映射的结果和实际类别吻合,而损失函数用来来衡量吻合度。

    zhuanxu
  • Cloudera 大数据平台介绍

    CDH:是Cloudera发布的一个自己封装的Hadoop商业版软件发行包,里面不仅包含了Cloudera的商业版Hadoop,同时CDH中也包含了各类常用的开...

    凹谷
  • 探究Java虚拟机栈

    Java 虚拟机的内存模型分为两部分:一部分是线程共享的,包括 Java 堆和方法区;另一部分是线程私有的,包括虚拟机栈和本地方法栈,以及程序计数器这一小部分内...

    Java团长
  • AngularJS单选框及多选框实现双向动态绑定

    ng-model指令用来将input、select、textarea或自定义表单控件同包含它们的作用域中的属性进行绑定。它将当前作用域中运算表达式的值同给定的元...

    奋飛
  • SILVER PEAK里程碑式的成功:拥有超过1000的全球客户

    Silver Peak今天宣布,目前该公司已经有超过1000的全球客户,现在正在进行的任务是将软件定义的广域网(SD-WANs)建设为一个单独的网络类别。

    SDNLAB
  • 游戏AI-实现AI角色的自主移动——操控行为

    这个类直译为“交通工具”包括了很宽泛的能自主移动的AI角色。 操作对象抽象为一个质点,包含位置信息、质量、速度等,速度随着施加力的变化而变化。力与速度都有一个...

    祝你万事顺利
  • 深度分享 | 世界顶级语音识别科学家黄学东博士CCL 2018主旨报告(附PPT)

    摘 要:在人类进化的长河中,语音和语言对人类智能自然选择起了独一无二的作用。可以毫不夸张的说是语音和语言推动了有别于动物的人类智能。在人工智能进化的短暂历...

    数据派THU
  • ES6之symbol

    ES6引入了一种新的原始数据类型Symbol,是第七种数据类型,表示独一无二的值。语法:

    wade

扫码关注云+社区

领取腾讯云代金券