代码之家  ›  专栏  ›  技术社区  ›  Bjarke Freund-Hansen najhi ullah

使用模板参数化接口中的类型映射遗留C接口

  •  3
  • Bjarke Freund-Hansen najhi ullah  · 技术社区  · 8 年前

    // c interface
    #include <stdint.h>
    #include <string.h>
    
    typedef enum {
        type_1 = 0, /* native type: uint8_t */
        type_2 = 1, /* native type: double */
        // ... lots of more types defined ...
    } thing_type_t;
    
    void thing_set(thing_type_t type, size_t type_size, void* value);
    void thing_get(thing_type_t type, size_t type_size, void* return_value);
    
    void thing_set_type_1(uint8_t value);
    void thing_get_type_1(uint8_t *value);
    
    void thing_set_type_2(double value);
    void thing_get_type_2(double *value);
    
    // ...
    

    所以基本上你可以 ,并以此为基础 thing_type_t 您可以选择相应的本机类型。这个接口我无法更改。

    现在我想做一个C++接口,使用类型多态性,所以我从一个客户端可以做一些类似的事情:

    // C++ client
    #include <cstdint>
    
    int main(void)
    {
        Thing thing;
        thing.set(std::uint8_t(42));
        thing.set(42.0);
    
        auto uivalue = thing.get<std::uint8_t>();
        auto dvalue = thing.get<double>();
    
        return 0;
    }
    

    事物类型 类型,但只使用相应的本机类型。

    // C++ interface
    #include <cstdint>
    
    class Thing
    {
    public:
        template <typename T> void set(T value);
        template <typename T> T get();
    };
    
    template <> void Thing::set(uint8_t value)
    {
        thing_set(type_1, sizeof value, reinterpret_cast<void*>(&value));
    }
    template <> std::uint8_t Thing::get()
    {
        uint8_t ret = 0;
        thing_get(type_1, sizeof ret, &ret);
        return ret;
    }
    
    template <> void Thing::set(double value)
    {
        thing_set(type_2, sizeof value, reinterpret_cast<void*>(&value));
    }
    template <> double Thing::get()
    {
        double ret = 0;
        thing_get(type_2, sizeof ret, &ret);
        return ret;
    }
    

    一、 e.我正在为每个 事物类型

    如何简化此操作,以便可以表示 事物类型

    我觉得我应该能够以某种方式用 事物类型 和本机类型以及映射。但我不知道怎么做。

    Online editable example

    2 回复  |  直到 8 年前
        1
  •  5
  •   Alan Birtles    8 年前

    由于实现之间唯一的变化是第一个参数,所以我将专门介绍这一部分:

    class Thing
    {
    public:
        template <typename T> void set(T value)
        {
            thing_set(getType<T>(value), sizeof value, reinterpret_cast<void*>(&value));
        }
        template <typename T> T get()
        {
            T ret = 0;
            thing_get(getType<T>(ret), sizeof ret, &ret);
            return ret;
        }
    
    private:
        template <typename T> thing_type_t getType(T);
    };
    
    template <> thing_type_t Thing::getType(uint8_t)
    {
        return type_1;
    }
    template <> thing_type_t Thing::getType(double)
    {
        return type_2;
    }
    
        2
  •  0
  •   Andrew Kashpur    8 年前

    类型映射.h

    macro(type_1, std::uint8_t)
    

    class Thing
    {
    public:
        template <typename T> void set(T value);
        template <typename T> T get();
    };
    
    #define macro(thing_type, actual_type) template <> void Thing::set(actual_type value) \
    {\
        thing_set(thing_type, sizeof value, reinterpret_cast<void*>(&value));\
    }\
    #include <typemap.h>
    #undef macro 
    
    #define macro(thing_type, actual_type) template <> actual_type Thing::get()\
    {\
        actual_type ret = 0;\
        thing_get(thing_type, sizeof ret, &ret);\
        return ret;\
    }\
    #include <typemap.h>
    #undef macro
    

    因此,最后只需修改typemap.h即可添加/删除专门化