您可以使用泛型来桥接不同的数据约定而不牺牲性能。
不足之处在于界面可能有更高的学习曲线。
首先,而不是接受矢量你可以接受迭代,其允许用户在其他容器中提供数据,例如阵列和列表。
template<typename AccessType, typename PosIter, typename VelIter>
void add_measurements(PosIter p1, PosIter p2, VelIter v1, VelIter v2)
{
// instantiate type to access coordinates
AccessType access;
// process elements
// Internal representation
std::vector<std::pair<double, double>> positions;
for(; p1 != p2; ++p1)
positions.emplace_back(access.x(*p1), access.y(*p1));
std::vector<std::pair<double, double>> velocities;
for(; v1 != v2; ++v1)
positions.emplace_back(access.x(*v1), access.y(*v1));
// do stuff with the data
}
然后,如果他们有一个奇怪的数据类型,他们想用这样的:
struct WeirdPositionType
{
double ra;
double dec;
};
他们可以创建一个类型访问其内部点坐标:
// class that knows how to access the
// internal "x/y" style data
struct WeirdPositionTypeAccessor
{
double x(WeirdPositionType const& ct) const { return ct.ra; }
double y(WeirdPositionType const& ct) const { return ct.dec; }
};
然后它被'插入'到通用功能:
int main()
{
// User's weird and wonderful data format
std::vector<WeirdPositionType> ps = {{1.0, 2.2}, {3.2, 4.7}};
std::vector<WeirdPositionType> vs = {{0.2, 0.2}, {9.1, 3.2}};
// Plugin the correct Access type to pull the data out of your weirt type
add_measurements<WeirdPositionTypeAccessor>(ps.begin(), ps.end(), vs.begin(), vs.end());
// ... etc
}
当然你也可以提供现成Access
类型共同点库如OpenCv
作者:
struct OpenCvPointAccess
{
double x(cv::Point2d const& p) const { return p.x; }
double y(cv::Point2d const& p) const { return p.y; }
};
然后使用可以简单地使用:
add_measurements<OpenCvPointAccess>(ps.begin(), ps.end(), vs.begin(), vs.end());
一个模板化的实现(在你的库的头部)是否可以? (这实质上会使.so无用)并且你需要支持双精度和浮点数吗?你会成为你图书馆的主要用户吗?还是你可以强制图书馆用户的任意接口? – chtz
IMO,使API“尽可能原始”意味着void add_measurements(const double * pos_data,const double * vel_data,size_t num_elements);'这将允许传递'Eigen :: Vector2d'的std :: vector'以及'std :: tuple'以及'cv :: Point2d'(由调用者进行一些编程工作,但在运行时没有拷贝开销) –
chtz