Colderleo's blog Colderleo's blog
首页
Linux
C++
Python
前端
工具软件
mysql
索引
关于
GitHub (opens new window)

Colder Leo

热爱代码的打工人
首页
Linux
C++
Python
前端
工具软件
mysql
索引
关于
GitHub (opens new window)
  • bug定位的一些情形
  • c++性能调优,可能的情况
  • total-编程知识点集锦
  • hpc_common.hpp
  • memory order 内存模型
  • 类型推导之auto-template-decltype
  • 完美转发forward源码分析
  • 左值和右值,右值引用、重载 std-move,引用折叠
  • cmake用法
  • alignas、alignof、sizeof实现内存对齐分配
  • 通过宏定义控制debug打印
  • 程序耗时性能测试
  • 线程池开源项目阅读
  • C++类中包含没有默认构造函数的成员
  • C++可变参数模板
  • C++属性继承 public protected private
  • C++智能指针
  • C++导出so的方法,以及extern C 注意事项
  • 四种spin lock
  • condition_variable和unique_lock
  • dpdk、kernel bypass
  • 智能网卡solarflare、Mellanox、X10等
  • 汇编寄存器和常见指令
  • c++ 类的静态成员变量未定义
  • C++获取类成员函数地址
  • preload示例
  • C++异常安全和RAII
  • C++11单例模式
  • C++歪门邪道
  • boost-program-option用法
  • c++17通过模板获取类成员的个数
  • 通过模板实现结构体成员拷贝-按成员名匹配
    • c++17 版本
    • c++11 版本
  • STL学习路径
  • boost库安装使用方法
  • C++文件读写
  • linux下socket通信demo,server和client
  • makefile写法
  • RxCpp
  • C++
gaoliu
2023-05-07
目录

通过模板实现结构体成员拷贝-按成员名匹配

# c++17 版本

#include <stdio.h>
#include <iostream>
#include <functional>
#include <type_traits>
#include <string.h>

using namespace std;


#define RegisterHasMember(MemName) \
template<typename T, typename=void> \
struct HasMember_##MemName  : std::false_type {}; \
template<typename T> \
struct HasMember_##MemName<T, std::void_t<decltype(T::MemName)>> : std::true_type {}; \


/**
 * expand: 
 *   template<typename T, typename=void> 
 *   struct HasMember_A : std::false_type {}; 
 *   template<typename T> 
 *   struct HasMember_A<T, std::void_t<decltype(T::A)>> : std::true_type {};
*/
RegisterHasMember(A)

RegisterHasMember(B)
RegisterHasMember(sid)
RegisterHasMember(tid)
RegisterHasMember(stype)
RegisterHasMember(ttype)
RegisterHasMember(stra)
RegisterHasMember(strb)
RegisterHasMember(AAA)
RegisterHasMember(BBB)

#define COPY_ONE_MEMBER(tmen, smen) \
if constexpr(HasMember_##tmen<Tar>::value && HasMember_##smen<Src>::value) { \
    tar.tmen = src.smen; \
}

#define COPY_ONE_MEMBER_WITH_FUNC(tmen, smen, func) \
if constexpr(HasMember_##tmen<Tar>::value && HasMember_##smen<Src>::value) { \
    func(tar.tmen, src.smen); \
}


template<typename Tar, typename Src>
void copy_member(Tar &tar, Src &src)
{

    /**
     * expand: 
     *    if constexpr(HasMember_tid<Tar>::value && HasMember_sid<Src>::value) {
     *        tar.tid = src.sid;
     *    }
    */
    COPY_ONE_MEMBER(tid, sid);

    COPY_ONE_MEMBER(ttype, stype);

    COPY_ONE_MEMBER(B, A);

    COPY_ONE_MEMBER(BBB, AAA);

    COPY_ONE_MEMBER_WITH_FUNC(strb, stra, strcpy);

}



struct ALogin {
    int sid;
    char stype;
    int A;
    char stra[9];
};

struct BLogin {
    long tid;
    char ttype;
    int B;
    char strb[9];
};


int main() {
    cout<< "ALogin has member A: " << HasMember_A<ALogin>::value <<endl;
    cout<< "BLogin has member A: " << HasMember_A<BLogin>::value <<endl;

    ALogin alogin {3, 5, 7, "dummy"};

    BLogin blogin{};

    copy_member(blogin, alogin);

    printf("after copy, blogin: %d,%d,%d,%s\n", 
        blogin.tid, blogin.ttype, blogin.B, blogin.strb);

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99

# c++11 版本

#include <stdio.h>
#include <type_traits>
#include <string.h>

using namespace std;

// c++17 can use std::void_t
template< class... >
struct void_st {
    using type = void;
};


// copy  Dst.dm  from  Src.sm 
#define REGISTER_COPY_MEMBER(dm, sm) \
template<typename Dst, typename Src, typename=void, typename=void>  \
struct copy_member_##dm##_from_##sm { \
    static void docopy(Dst &dst, Src &src) {} \
};  \
template<typename Dst, typename Src>  \
struct copy_member_##dm##_from_##sm < Dst, Src, typename void_st<decltype(Dst::dm)>::type, typename void_st<decltype(Src::sm)>::type > { \
    static void docopy (Dst &dst, Src &src) { \
        dst.dm = src.sm; \
    } \
    template<typename Func> \
    static void docopy (Dst &dst, Src &src, Func f) { \
        f(dst.dm, src.sm); \
    } \
}; \


#define COPY_ONE_MEMBER(dm, sm) copy_member_##dm##_from_##sm<Dst, Src>::docopy(dst, src)
#define COPY_ONE_MEMBER_WITH_FUNC(dm, sm, f) copy_member_##dm##_from_##sm<Dst, Src>::docopy(dst, src, f)


/**
 * expand:
 *    template<typename Dst, typename Src, typename=void, typename=void> 
 *        struct copy_member_B_from_A { static void docopy(Dst &dst, Src &src) {} 
 *    }; 
 *    template<typename Dst, typename Src> 
 *    struct copy_member_B_from_A < Dst, Src, std::void_t<decltype(Dst::B)>, std::void_t<decltype(Src::A)> > { 
 *        static void docopy (Dst &dst, Src &src) { dst.B = src.A; } 
 *        template<typename Func> 
 *        static void docopy (Dst &dst, Src &src, Func f) { f(dst.B, src.A); }
 *    };
*/
REGISTER_COPY_MEMBER(B, A);

REGISTER_COPY_MEMBER(dtype, stype);
REGISTER_COPY_MEMBER(id, id);
REGISTER_COPY_MEMBER(strb, stra);
REGISTER_COPY_MEMBER(NotExist, NotExist);

template<typename Dst, typename Src>
static void copy_member(Dst &dst, Src &src)
{
    // copy_member_B_from_A<Dst, Src>::docopy(dst, src)
    COPY_ONE_MEMBER(B, A);

    COPY_ONE_MEMBER(dtype, stype);
    COPY_ONE_MEMBER(id, id);
    COPY_ONE_MEMBER(NotExist, NotExist);

    // copy_member_strb_from_stra<Dst, Src>::docopy(dst, src, strcpy)
    COPY_ONE_MEMBER_WITH_FUNC(strb, stra, strcpy);
}



struct ALogin {
    int A;
    char stype;
    int id;
    char stra[9];
};

struct BLogin {
    long B;
    char dtype;
    long id;
    char strb[9];
};


int main() {
    ALogin alogin {3, 5, 7, "dummy"};
    BLogin blogin{};

    copy_member(blogin, alogin);

    printf("after copy, blogin: %d,%d,%d,%s\n", 
        blogin.B, blogin.dtype, blogin.id, blogin.strb);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
编辑 (opens new window)
上次更新: 2023/05/09, 01:45:50
c++17通过模板获取类成员的个数
STL学习路径

← c++17通过模板获取类成员的个数 STL学习路径→

最近更新
01
c++17通过模板获取类成员的个数
05-01
02
avx-sse切换惩罚
04-30
03
动态库和静态库的依赖问题
04-30
更多文章>
Theme by Vdoing | Copyright © 2019-2023 Colder Leo | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×