• 三味
    2019-12-30
    emmmm....
    这一节内容如果是半年前看到,应该能节省我好多时间去写序列化,真是我实实在在的需求啊!
    我自己在写数据序列化为json文本的时候,就遇到了这样头疼的问题:如何根据类型,去调用对应的函数。
    如果是简单的int,bool,float,直接特化就好了。
    如果是自定义的结构体呢?我的做法就是判断自定义结构体中是否有serializable和deserializable函数,就用到了文中最开始的方法判断。
    然而那会儿我写得还是太简单粗暴,在代码中用的是if去判断,对于不支持的类型,直接报错,并不能做到忽略。
    看了本文之后,真是受益颇多啊!留言于此,告诉大家,别以为用不到这些内容,都是实实在在的干货!
    展开

    作者回复: 我喜欢这样的留言。哈哈,写专栏就是希望能给大家帮助的。😇

    
     6
  • 禾桃
    2019-12-27
    请问有编译器本身什么工具或者日志模式,可以显示模版实例化的过程?

    作者回复: 新发现一个工具,可以展示实例化的过程。你可以去看一下:

    https://cppinsights.io/

    
     3
  • 曹哲铭
    2020-01-17
    表示真的太烧脑了

    作者回复: 这个网站也许可以帮你:

    https://cppinsights.io/

    
    
  • 光城~兴
    2020-01-07
    假设U是一个Class,内部有foo方法与bar方法,那么U::*表示的是所有成员函数的指针吧,而U::foo*是foo成员函数指针,还请老师指点。

    作者回复: 你的问题不那么清楚啊。

    U::* 不是完整类型,void (U::*)() 才是一个类型。U::foo 是一个具体的函数,&U::foo 是函数指针。

    
    
  • 木瓜777
    2020-01-02
    没看这几篇文章前,以为理解模板了,现在才知道模板博大精深👍

    作者回复: 写这一讲时,我自己也觉得很舒心——正好把相关的技巧整理一遍。这部分还是挺复杂的。

    
    
  • 李亮亮
    2019-12-30

    template <typename T,
              typename = void_t<>>
    struct has_reserve : false_type {};
    这里的冒号是什么语法?

    作者回复: 继承啊。

     1
    
  • 总统老唐
    2019-12-29
    吴老师,关于这一课,有 3 个问题
    1,在最开始定义 has_reserve 类时,两个 reserve 模板函数实际上只是声明了,但是并没有真正的函数体,而最后的 value 成员实际上是用 nullptr 调用了 reserve 函数,这就相当于调用一个没有只有声明没有定义的函数,为什么没有报错?
    2,关于模板函数的调用
    假设有如下模板
    template <typename T1, typename T2>
    int add(T1 a, T2 b);
    既可以add<int, double>(1, 2.5)调用,也可以add(1, 2.5)调用,两者的差别是不是第一种方式相当于先声明了一个特化版本,在用这个特化版本来调用,后一种方式是编译器自行推断?但若是没有定义对应的特化版本,第一种方式和第二种方式是不是完全没有区别?
    3,在 void_t 的部分,模板定义时,第二个参数是这样写的:typename = void_t<>, 我试了一下,直接写成 typename = void,也是可以的,你采用这种写法是有什么特殊考虑吗?
    展开

    作者回复: 1. 一个函数没有真正被调用,代码里就不会产生对它的引用,链接没有也就不会出问题。

    2. 不是特化,而是自动推断后进行自动实例化。特化是需要有能看得到的特化定义的。

    3. 主要是和下面的定义对称。因为这儿的类型不实际使用,写任何的合法类型都是可以的。

    
    
  • 禾桃
    2019-12-27
    “
    template <typename T, typename = void_t<>>
    struct has_reserve : false_type {};

    template <typename T>
    struct has_reserve<T, void_t<decltype(declval<T&>().reserve(1U))>> : true_type {};

    declval().reserve(1U) 用来测试 C& 类型的对象是不是可以拿 1U 作为参数来调用 reserve 成员函数
    “
    请问
    - 如果是, decltype(declval<T&>().reserve(1U))> 返回的是void,这个好理解,因为void_t会把任何数目(包括零个)的类型转换为类型void
    - 如果不是, 编译器看到decltype(declval<T&>().reserve(1U))> 会做什么?
                      然后编译器看到void_t<decltype(declval<T&>().reserve(1U))> 又会做什么?
    展开

    作者回复: 不是说了吗,把任意类型映射到void。任意类型哦……只要表达式合法就行。

     2
    
我们在线,来聊聊吧