我有一个(遗留的)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);
// ...
所以基本上您可以设置thing,并且根据您选择的thing_type_t
有相应的 native 类型。这个界面我不能改变。
现在我想利用类型多态性做一个 C++ 接口(interface),所以我从客户端可以做类似的事情:
// 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;
}
它不必完全像这样,但想法是客户端不必担心内部 thing_type_t
类型,而只需使用相应的 native 类型。
我想到的是使用这样的模板:
// 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;
}
即我正在为每个 thing_type_t
进行类型专门化,这导致代码臃肿,包含大量重复代码。
我该如何简化它,以便表达 thing_type_t
和 native 类型之间的映射,而无需一次又一次地复制 get/set 函数?
我觉得我应该能够以某种方式使用 thing_type_t
和 native 类型以及映射来参数化 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;
}
关于c++ - 在接口(interface)映射遗留 C 接口(interface)中使用模板参数化类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51820391/