Было бы разумно обеспечить преобразование из Points3DTopoList в PointsList, учитывая, что Point3DTopo является производным от Point. Наследование, которое обеспечивает это преобразование автоматически, возможно, но я подозреваю, что ваши требования к общедоступному интерфейсу (опущенные в вопросе) делают его скорее хлопотным, чем активом.
Пример предоставления пути конверсии:
template<class T>
struct PointsList {
// Points3DTopoList needs a way to construct a PointsList
template<class Iter>
PointsList(Iter begin, Iter end)
: points(begin, end)
{}
private:
std::vector<Point<T> > points;
};
template<class T>
struct Points3DTopoList {
operator PointsList<T>() const {
return PointsList<T>(points.begin(), points.end());
}
PointsList<T> to_points_list() const {
return PointsList<T>(points.begin(), points.end());
}
private:
std::vector<Point3DTopo<T> > points;
};
Это обеспечивает два пути конверсии — обычно вы выбираете один и не предоставляете другой. Оператор преобразования является неявным преобразованием (в C++0x вы можете пометить его как явное), в то время как именованный метод не является «преобразованием» с технической точки зрения (поэтому никогда не применяется для любого неявного или явного преобразования), а вызывается явно и использовал таким образом.
Вы также можете обеспечить явное преобразование с помощью явного конструктора в PointsList, который принимает Points3DTopoList, и это работает в текущем C++ за счет инвертирования отношения зависимости от того, как оно обычно лежит: то есть PointsList будет знать и заботиться о Points3DTopoList вместо этого. наоборот.
Тем не менее, может иметь смысл предоставить контейнер "generic-Point"; то есть тот, который принимает любой конкретный Point-подобный тип.
template<class Point>
struct GenericPointContainer {
private:
std::vector<Point> points;
};
Самая большая сила здесь заключается в том, что методы GenericPointContainer могут использовать различные функции из производных классов Point, которых нет в самой Point, но которые все же могут быть созданы непосредственно в Point. Это работает, потому что не все методы создаются при создании экземпляра шаблона класса, и практическим примером является то, как std::reverse_iterator перегружает оператор +=, который работает только для итераторов с произвольным доступом, но может быть создан для итераторов без произвольного доступа, например, std::reverse_iterator‹std::list‹int>::iterator>.
Затем различные классы списков могут стать простыми определениями типов, если они все еще требуются:
typedef GenericPointContainer<Point<int> > PointsList;
typedef GenericPointContainer<Point3DTopoList<int> > Points3DTopoList;
С++ 0x действительно поможет вам здесь с определениями типов шаблонов (вы можете использовать повторную привязку в текущем С++, но это становится тупым); как вы можете видеть, мне пришлось указать T для typedefs, так что это не так часто, как в противном случае.
person
Fred Nurk
schedule
18.01.2011
reinterpret_cast
, вам просто нужно потратить время на то, чтобы преобразовать один контейнер в другой по пунктам. Вот и все. Здесь нет никаких трюков, они вам не нужны, просто простой цикл. И снова прекратите динамически распределять все подряд! - person GManNickG   schedule 18.01.2011