代码改变世界

一个泛型编程方法的妙用

2015-05-20 10:50  刘腾达的博客  阅读(471)  评论(0编辑  收藏  举报

项目用到了 Mysql,有很多相似代码,从一个表中取数据,赋值给一个结构体。将问题简化一下,如同这样:

  结果集 A
    row_a[][128] = {"name", "20", "1000"};

    结构体 A
    struct A {
        char name[32]; 
        int age; 
        int money;
    };

    结果集 B
    row_b[][128] = {"jimmy", "100", "500", "1000", "lucy"};

    结构体 B
    struct B { 
        char name[32]; 
        int p1; 
        int p2; 
        int p3; 
        char girlfriend[32]; 
    };

 

写一个函数 func,能够用如下的方式,将不同的结果集分别赋值给对应的结构体。

    A a;
    B b;

    func(&a, row_a);
    func(&b, row_b);

 

技巧一,在结构体中增加 static 成员变量,记录其成员类型信息。

    struct A {
        static char keysinfo[];
        char name[32];
        int age;
        int money;
    };
    char A::keysinfo[] = "sii";

    s 表示字符串,定长 32 字节
    i 表示 int

 

技巧二,写一个模板函数 func,大致的方法如下:

    template <typename T, int M, int N>
    void func(T* st, const char (&str)[M][N]) {
        char * ptr = reinterpret_cast<char *>(st);

        for (int i = 0; i < M; ++i) {
            if (T::keysinfo[i] == 'i') {
                auto p = reinterpret_cast<int *>(ptr);
                *p = atoi(str[i]);
                ptr += 4;
            } else if (T::keysinfo[i] == 's') {
                strncpy(ptr, str[i], 32);
                ptr += 32;
            }
        }
    }

 

接下来,就实现了我们最初的想法,一个函数可以给不同的结构体赋值咯。
    A a;
    char str[][128] = {"jimmy", "123", "456"};
    func(&a, str);

    B b;
    char str[][128] = {"billy", "1000", "500", "100", "lucy"}
    func(&b, str);