CGAL 概念模型及Traits
本节释了概念Concepts
、模型Models
以及Traits
类的含义。
CGAL Concepts and Models
概念Concepts
是对类型的一组要求,即它具有特定的嵌套类型、特定的成员函数或具有特定的以该类型为参数的自由函数。概念的模型 Models
是一个满足概念需求的类。
示例
template <typename T>
T duplicate(T t)
{
return t;
}
如果想用一个类 C 来实例化这个函数,这个类必须至少提供一个复制构造函数,而且我们说 类C 必须是 CopyConstructible
的模型。单例类不能满足这个要求。
CopyConstructible
是一个概念,可构造拷贝的概念;这里类C是一个模型。
template <typename T>
T& std::min(const T& a, const T& b)
{
return (a<b)?a:b;
}
只有当 operator<(…) 是为 T 类型定义的,并且我们说该类型必须是LessThanComparable
的模型时,这个函数才能编译。
LessThanComparable
是概念,凡是重载operator<(…)操作的类T都是LessThanComparable
的模型。
Kernels and Traits Classes
template<class InputIterator , class OutputIterator , class Traits >
OutputIterator convex_hull_2(
InputIterator first,
InputIterator beyond,
OutputIterator result,
const Traits & ch_traits)
典型的凸包算法使用什么几何基元?当然,这取决于算法,所以让我们考虑一下什么可能是最简单的高效算法,即所谓的“Graham/Andrew Scan”。该算法首先对点集进行从左到右的排序,然后从排序列表中一个接一个地添加点,增量地构建凸包。要做到这一点,它必须至少知道一些点的类型
,它应该知道如何对这些点排序
,而且它必须能够评估三个点的方向
。
这就是模板参数 Traits
的作用。
对于 ch_graham_andrew()
,它必须提供以下嵌套类型:
- Traits::Point_2
- Traits::Less_xy_2
- Traits::Left_turn_2
- Traits::Equal_2
Left_turn_2
负责方向测试,而Less_xy_2
用于对点进行排序。这些类型必须满足的要求以ConvexHullTraits_2
的概念完整记录。
template <class InputIterator,
class OutputIterator,
class Point_2, class Less_xy_2, class Left_turn_2, class Equal_2>
OutputIterator ch_graham_andrew(
InputIterator first,
InputIterator beyond,
OutputIterator result);
任何CGAL中的概念 Kernel
的模型提供了 ConvexHullTraits_2
概念所需要的东西。
总结
- 概念
Kernel
的模型Point_2
、和Point_3
都提供了ConvexHullTraits_2
概念所需要的东西。 - 概念
BGL Graph
的模型有Surface_mesh
,Polyhedron
,Arrangement_2
,和2D triangulation classes
都提供了boost::graph_traits
概念所需的东西。
在图模型上操作的算法在类boost::graph_traits
的帮助下确定类型。这些类型是 vertex_descriptor
,类似于CGAL
数据结构中的顶点句柄,或 edge_descriptor
,类似于半边数据结构中的半边句柄或二维三角网格中的类型边。还有一种迭代器,比如类似于CGAL
数据结构中的顶点迭代器的 vertex_iterator
,以及类似于边循环器的 out_edge_iterator
;它能够迭代与一个顶点相关的边。这两个迭代器是相似的,但并不等价,因为它们的值类型是 vertex_descriptor
,而在CGAL
句柄中,迭代器和循环器的值类型都是相同的,即顶点类型或边类型。
boost::graph_traits<Graph>::vertex_descriptor vd;
boost::graph_traits<Graph>::edge_iterator ei;
...
这里的Graph
可以是Surface_mesh
, Polyhedron
, Arrangement_2
,和2D triangulation classes
。
template < class VertexListGraph, class Param, class Tag, class Rest >
inline void dijkstra_shortest_paths(const VertexListGraph& g,
typename graph_traits< VertexListGraph >::vertex_descriptor s,
const bgl_named_params< Param, Tag, Rest >& params)
{}
算法dijkstra_shortest_paths
的第一个参数是图的模型,第二个参数是boost::graph_traits
用于确定类型。
相关内容
示例1
template <typename T>
diff_int(T t,ture_type)
{
}
template <typename T>
diff_int(T t,false_type)
{
}
template <typename T>
void diff(T t)
{
//决定调用哪一个函数
diff_int(t,std::is_integral<T>());
}
示例2
traits
:
template<typename Iterator, typename T>
void func_impl(Iterator iter, T t)
{
T temp;//这里就解决了问题
}
template<typename Iterator>
void func(Iterator iter)
{
func_impl(iter, *iter);//func的工作全部都移到func_impl里面了
}
int main(int argc, const char *argv[])
{
int i;
func(&i);
}
示例3
STL
参考及相关链接
- https://doc.cgal.org/latest/Manual/tutorial_hello_world.html
- STL源码解析
- CGAL Hello World
- C++核心编程——初识STL——STL的基本概念和六大组件