使用相同的基础数据结构处理不同类型

时间:2011-10-07 19:09:04

标签: c++ c casting mixing

我需要在计算机模拟中将C代码与C ++代码混合使用。

C库具有引用常规双精度数组的函数:

void position(double[3])

另一个C库定义了自己的vector类型:

void do_something(*custom_vector)

我的前端(使用C ++)使用boost::numeric::ublas::vector

在第一种情况下,我有很多地方都有这种代码:

double tmp[3];
position(tmp)
boostvec r(3);
r(0) = tmp[0]; r(1) = tmp[1]; r(2) = tmp[2];
// continue working with r

custom_vector *v;
do_something(v);
boostvec r(3);
r(0) = v[0]; r(1) = v[1]; r(2) = v[2];

在内部,所有类型都是最终的矢量容器,但它们的轻微实现差异导致了很多样板爆炸。我还处理了很多不同版本的double(一些定义realtype(这是一个双重),其他定义number(这是一个双倍)等。

你如何处理这种情况?

谢谢。

2 个答案:

答案 0 :(得分:2)

只要源类型和目标类型都支持标准迭代器接口(对于std :: vector,数组以及我能想到的每个Boost序列类型都是如此;所以你只需要修复你的custom_vector),并且只要数字类型之间存在隐式转换,您应该只能使用std::copy

答案 1 :(得分:2)

如果你在这两种数据类型之间进行翻译,你可能应该写很多样板。无论你涂上多少口红,它总是会做同样的操作。

当你看到像realtype之类的东西的typedef时,这对我来说是一个代码味道,有人正在过早地抽象数据。在较低级别编写数据抽象往往会使接口“爆炸”。如果您以最愚蠢的方式使用数据容器,通常情况下会更好。不要用它们来保护不变量,只需存储数据。在算法级别进行抽象,并以最简单的形式保留数据。

重构其他代码可能有意义使用一致的东西,但通常是旧代码或外代码。在你的新发展中,要理智并使用载体。编写适配器以在它们之间进行转换,然后让旧代码继续在您的单板后面吮吸。

我最开心的就是让这些问题变得非常糟糕,就是使用指针和长度。诚然,这违背了大多数建议。

void foo(double *data, size_t len);

它会产生丑陋(且容易出错)的代码,但它是最低的共同点。如果你可以将它隐藏在非常明显的私有实现中。

我最后写了很多无法重复使用的助手。结果,代码具有可怕的局部性,我的意图并不明显。