Names, in particular (member) function names and class names should be descriptive and easily remembered. So it is not surprising that different libraries or packages choose the same name for corresponding or similar classes and functions. A common approach to solving the naming problem is to add a prefix, for example, OpenGL adds gl and FLTK adds fl. LEDA uses prefix leda_ to some extent, but you have to tell LEDA not to make the corresponding unprefixed names available as well.1 Initially, CGAL used prefix CGAL_. At the beginning of 1999, it was decided to drop prefix CGAL_ and to introduce namespace CGAL.
using CGAL::Object; Object obj; // name is now knownThere is also a statement to make all names from a namespace available in another scope, but this is a bad idea. Actually, in order not to set a bad example, we recommend not to use this in CGAL's example and demo programs.
std::cout << "Hello CGAL" << std::endl;or you have to add using declarations for the names you want to use without std:: qualification. Whenever a platform does not put names into namespace std, CGAL adds the names it needs to namespace std. This is done by the configuration tools.
As for the C-library functions, you should use the macro CGAL_CLIB_STD instead of std:
CGAL_CLIB_STD::isspace(c)
#include <something> namespace CGAL { class My_new_cgal_class {}; My_new_cgal_class my_new_function( My_new_cgal_class& ); } // namespace CGALMake sure not to have include statements nested between namespace CGAL { and } // namespace CGAL. Otherwise all names defined in the file included will be added to namespace CGAL. (Some people use the macros CGAL_BEGIN_NAMESPACE and CGAL_END_NAMESPACE in place of the namespace CGAL { and } // namespace CGAL, respectively, for better readability.)
namespace A { template <class T> const T& mix(const T& a1, const T& a2) { return a1 < a2 ? a1 : a2; } template <class T> const T& use(const T& a1, const T& a2) { return mix( a1, a2); } } // namespace A namespace B { template <class T> const T& mix(const T& a1, const T& a2) { return a2 < a1 ? a1 : a2; } double use_use( const double& t1, const double& t2) { return A::use(t1,t2); } } // namespace B int main() { B::use_use( 0.0, 1.0); return 0; }
There is a ambiguity, because both the scope enclosing the point of instantiation and the scope enclosing the point of definition contain a mix function. The mips compiler on IRIX complains about this ambiguity:
bash-2.03$ CC -64 poi.cpp
cc-1282 CC: ERROR File = poi.cpp, Line = 11
More than one instance of overloaded function "mix" matches the argument list.
Function symbol function template "B::mix(const T &, const T &)"
is ambiguous by inheritance.
Function symbol function template "A::mix(const T &, const T &)"
is ambiguous by inheritance.
The argument types are: (const double, const double).
{ return mix( a1, a2); }
^
detected during instantiation of
"const double &A::use(const double &, const double &)"
1 error detected in the compilation of "poi.cpp".
There wouldn't be any problems, if B::use_use() would be a template
function as well, because this would move the point of instantiation
into global scope.
By the way, gcc 2.95 uses the function defined at the point of definition.
Note: This section will be revised once the forthcoming revision of the C++-standard gets into a more definite state. The standard library has similar problems, e.g. for swap(), see issues 225, 226, and 229. Currently, CGAL::NTS does not exist anymore, and the CGAL_NTS macro boils down to CGAL::. As the future interface is not yet fixed, people should still follow the guidelines given below.
What are the conclusions from the previous subsection. If A plays the role of std and B the role of CGAL, we can conclude that CGAL should not define template functions that are already defined in namespace std, especially min and max. Also, letting CGAL be namespace A, we should not define templates in CGAL that are likely to conflict with templates in other namespaces (playing the role of B): Assume that both CGAL and some other namespace define an is_zero() template. Then an instantiation of some CGAL template using is_zero() that takes place inside the other namespace causes trouble. For this reason, we have another namespace NTS nested in CGAL, which contains potentially conflicting template functions.
if ( CGAL_NTS is_zero(0) ) { /* ... */ }Qualification with CGAL does not work.
1 | CGAL's makefile does this by setting -DLEDA_PREFIX. |
2 | There are also unnamed namespaces. They are intented to replace file scope. |
3 | This is a somewhat simplified view; read further for more details. |
4 | The use of the macro eases future changes in our policy. |