Я хочу ввести набор точек в библиотеку, где каждая точка набора состоит из набора координат. Мне бы хотелось, чтобы ввод был максимально гибким в отношении того, как пользователь библиотеки выбирает представление своих данных.
Так что я хотел бы иметь возможность вызвать следующий псевдокод
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);
}
ЮК. Есть ли приемлемый способ сделать это? Если нет, есть ли способ как-то убрать шум шаблона в библиотеку, чтобы мне не приходилось писать такой код для каждого контейнера, который я пишу.