【发布时间】:2011-11-30 11:05:01
【问题描述】:
我想将一组点输入到库中,其中该组的每个点都包含一组坐标。我希望输入对图书馆用户选择表示他们的数据的方式尽可能灵活。
所以我希望能够调用下面的伪代码
template<int dimenension> //the dimension of each of the points
struct set_of_points
{
void insert(Iterator first_point, Iterator last_point);
}
来自以下任何一个,
struct set_of_points<2> s;
double points1[3][2] = {
{1,2},
{2,3},
{4,5}
};
s.insert(points1, points1+3);
double p1[2] = {1,2}, p2[2] = {2,3}, p3[2] = {4,5};
double* points2[3] = {p1,p2,p3};
s.insert(points2, points2+3);
std::vector<double*> points3;
points3[0] = p1; points3[1] = p2; points3[2] = p3;
s.insert(points3.begin(), points3.end())
我也可以将vector<vector<double> > 和vector< boost::array<double,2> > 添加到该列表中。
我能想到的唯一方法是使用扩展的、丑陋的和手工制作的模板魔法。比如数组的指针和指针和指针都可以这样做。
#include<iostream>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_array.hpp>
#include <boost/type_traits/is_pointer.hpp>
#include <boost/mpl/if.hpp>
#include <boost/type_traits/remove_pointer.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/or.hpp>
template<int dimenension> //the dimension of each of the points
struct set_of_points
{
// The coordinates of each point are represented as an array or a set of pointers,
// And each point is in an array.
template<typename PointsItr>
void
insert(PointsItr P_begin, PointsItr P_end,
typename boost::enable_if< //enable if
typename boost::mpl::and_<
boost::is_pointer< PointsItr >, //The set of points is a pointer, AND
typename boost::mpl::or_< //either
boost::is_array<typename boost::remove_pointer< PointsItr >::type >, //The points are an array
boost::is_pointer<typename boost::remove_pointer< PointsItr >::type > //or are pointers
>::type //close or
>::type //close and
>::type* dummy = 0)
{
std::cout<<"inserted pointer of (pointers OR array)"<<std::endl;
}
};
int
main (int ac, char **av)
{
struct set_of_points<2> s;
double points1[3][2] = {
{1,2},
{2,3},
{4,5}
};
s.insert(points1, points1+3);
double p1[2] = {1,2}, p2[2] = {2,3}, p3[2] = {4,5};
double* points2[3] = {p1,p2,p3};
s.insert(points2, points2+3);
}
哎呀。有没有一种可维护的方式来做到这一点?如果没有,有没有办法以某种方式将模板噪音整理到库中,这样我就不必为我编写的每个容器编写这样的代码。
【问题讨论】:
-
听起来非常复杂,为什么不定义一些受限的
point类型(point2d、point3d等),然后简单地接受这些点的迭代器范围以插入到您的集合中?跨度> -
@Nim,没想到会这么复杂。我希望我的库能够“正常工作”,而用户每次使用该库时都不必重新打包他们的数据。不过,您的解决方案更简单——至少这样我可以保证
begin()和end()方法。 -
冒着听起来像 80 年代冲浪者的风险,那是一些粗糙的代码花花公子。
-
你为什么不写另一个模板类并传递你的坐标。并计算数组的长度并在其中编写两个函数 begin() 和 end()。?将更具可扩展性
标签: c++ templates generics containers