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

C++ 在映射遗留C接口的接口中使用模板参数化类型,c++,templates,C++,Templates,我有一个(遗留)c接口,看起来像这样: // 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; voi

我有一个(遗留)c接口,看起来像这样:

// 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);

// ...
// 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;
}
它不必与此完全相同,但其思想是客户机不必担心内部
类型\u t
类型,而只需使用相应的本机类型

我想到的是使用如下模板:

// 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);

// ...
// 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;
}
<代码> /C++接口 #包括 阶级事务 { 公众: 模板无效集(T值); 模板T get(); }; 模板void Thing::set(uint8\u t值) { 事物集(类型1、大小值、重新解释类型(&value)); } 模板std::uint8\u t Thing::get() { uint8_t ret=0; 获取的对象(类型1、大小ret和ret); 返回ret; } 模板void Thing::set(双值) { 事物集(类型2、大小值、重新解释类型(&value)); } 模板double Thing::get() { 双ret=0; 获取的内容(类型2、ret大小和ret); 返回ret; } 也就是说,我正在为每个
东西\u type\t
进行类型专业化,这会导致大量代码和大量重复代码的膨胀代码

如何简化此操作,以便在不重复get/set函数的情况下,表达
对象类型与本机类型之间的映射?

我觉得我应该能够以某种方式用
thing\u type\t
和本机类型以及映射来参数化get和set函数。但我不知道该怎么做


因为实现之间唯一的变化是第一个论点,我只专门讨论这一部分:

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;
}
类的东西
{
公众:
模板无效集(T值)
{
设置对象(getType(value)、sizeof value、重新解释类型(&value));
}
模板T get()
{
T-ret=0;
获取的内容(getType(ret)、ret的大小和ret);
返回ret;
}
私人:
模板对象类型getType(t);
};
模板对象类型对象::getType(uint8\t)
{
返回类型_1;
}
模板对象类型对象::getType(双精度)
{
返回类型_2;
}

宏在这种情况下会有所帮助:

typemap.h 事情
类的东西
{
公众:
模板无效集(T值);
模板T get();
};
#定义宏(对象类型,实际对象类型)模板void thing::set(实际对象类型值)\
{\
设置对象(对象类型、大小值、重新解释类型(&value))\
}\
#包括
#未定义宏
#定义宏(对象类型,实际对象类型)模板实际对象类型对象::get()\
{\
实际类型ret=0\
获取对象(对象类型、ret大小和ret)\
返回ret\
}\
#包括
#未定义宏

因此,最终您只需修改typemap.h即可添加/删除专门化,原因很简单:)非常感谢你。
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