?? tour-stdcxx.html
字號:
<html><head><title>A Tour of NTL: Traditional and ISO Modes </title></head><body bgcolor="#fff9e6"><center><a href="tour-modules.html"><img src="arrow1.gif" alt="[Previous]" align=bottom></a> <a href="tour.html"><img src="arrow2.gif" alt="[Up]" align=bottom></a> <a href="tour-unix.html"> <img src="arrow3.gif" alt="[Next]" align=bottom></a></center><h1> <p align=center>A Tour of NTL: Traditional and ISO Modes</p></h1><p> <hr> <p><p>As of version 4.1,NTL can be compiled and used in one of two modes: Traditional or ISO.To get ISO mode, you can pass <tt>NTL_STD_CXX=on</tt>as an argument to the configuration scriptwhen <a href="tour-unix.html">installing NTL on a Unix or Unix-like system</a>.This will set the flag <tt>NTL_STD_CXX</tt> in the <tt>config.h</tt>file.Alternatively (and especially on non-Unix systems),you can set this flag by hand by editing the the <tt>config.h</tt> file.<p>Traditional mode provides the same interface as that provided in versions 4.0 and earlier.Traditional mode is also the default, so old programs that used NTLshould continue to work without any changes.So if you wish, you can completely ignore the new ISO mode, and ignorethe rest of this page.However, if you want to fully exploit some important,new features of <tt>C++</tt>, in particular <i>namespaces</i>, read on.Also, it is likely that in future distributions of NTL, ISO mode will becomethe default mode, although Traditional mode will continue tobe supported indefinitely.<p>In Traditional mode, the NTL header files include the traditional<tt>C++</tt> header files <tt><stdlib.h></tt>,<tt><math.h></tt>, and <tt><iostream.h></tt>.These files declare a number of names (functions, types, etc.)in the <i>global namespace</i>.Additionally, the NTL header files declare a number of names,also in the global namespace.<p>In ISO mode, the NTL header files include the new <tt>C++</tt> header files <tt><cstdlib></tt>,<tt><cmath></tt>, and <tt><iostream></tt>.These new header files are essentially the same as the traditional ones,except that all the the names are declared in a namespace called <tt>std</tt>.Additionally, the NTL header files declare a number of names,but these are all declared within a namespace called <tt>NTL</tt>.<p>ISO mode uses <tt>C++</tt> features that are new tothe new ISO <tt>C++</tt> standard.I know of no compiler that truly implements all of the standard,but some come pretty close.If your complier is too old, you will not be able to use NTL in ISO mode; otherwise, you are free to use either ISO or Traditional mode,but I would recommend ISO mode for code that you expect tobe around for a long time.In particular, if you want to develop and distribute a library thatbuilds on top of NTL, it would be preferable to make it compatiblewith NTL in ISO mode, and even better, to make it compatible witheither mode.<p>The upshot is, NTL will remain usable in Traditional indefinitely,assuming compilers maintain reasonable backward compatibilty with pre-standard <tt>C++</tt> conventions for header files;however, if you want to <i>program for the future</i>, it is recommendedto use ISO mode.<p><h3>A crash course on namespaces</h3><p>As already mentioned, the main difference between Traditional and ISOmode is that in ISO mode, all names are wrapped in namespaces.Namespaces are a feature that was introduced in the new <tt>C++</tt> standard.One can declare names (functions, types, etc.) inside a namespace.By default,such names are not visible outside the namespace without explicitqualification.<p>The main advantage of namespaces is that it solves the <i>namespace pollutionproblem</i>:if two libraries define the same name in two inconsistent ways,it is very difficult, if not impossible,to combine these two libraries in the same program.<p>The traditional way of avoiding such problems in languages like<tt>C</tt> is for a library designer to attach a prefix specificto that library to all names.This works, but makes for ugly code.The function overloading mechanism in <tt>C++</tt> eases the problem a bit,but is still not a complete solution.<p>The newnamespace feature in <tt>C++</tt>provides a reasonably complete and elegant solution to the namespacepollution problem.It is one of the nicest and most important recent additions to the <tt>C++</tt>language.<p>Here is a simple example to illustrate namespaces.<p><pre>namespace N { void f(int); void g(int); int x;}int x;void h(){ x = 1; // the global x N::x = 0; // the x in namespace N N::f(0); // the f in namespace N g(1); // error -- g is not visible here}</pre><p>All of this explicit qualification businesscan be a bit tedious.The easiest way to avoid this tedium is to use what is calleda <i>using directive</i>, which effectively makesall names declared within a namespace visible in theglobal scope.Here is a variation on the previous example, with a using directive.<p><pre>namespace N { void f(int); void g(int); int x;}int x;using namespace N;void h(){ x = 1; // error -- ambiguous: the global x or the x in namespace N? ::x = 1; // the global x N::x = 0; // the x in namespace N N::f(0); // the f in namespace N f(0); // OK -- N::f(int) is visible here g(1); // OK -- N::g(int) is visible here}</pre><p>Here is another example.<p><pre>namespace N1 { int x; void f(int); void g(int);}namespace N2 { int x; int y; void f(double); void g(int);}using namespace N1;using namespace N2;void h(){ x = 1; // error -- ambiguous: N1::x or N2::x? N1::x = 1; // OK N2::x = 1; // OK y = 1; // OK -- this is N2::y g(0); // error -- ambiguous: N1::g(int) or N2::g(int)? f(0); // OK -- N1::f(int), because it is the "best" match f(0.0); // OK -- N2::f(double), because it is the "best" match}</pre><p>This example illustrates the interaction between using declarationsand function overloading resolution.If several overloaded versions of a function are visible,it is not necessarily ambiguous: the usual overload resolutionprocedure is applied, and if there is a unique "best" match,then there is no ambiguity.<p>The examples presented here do not illustrate all of thefeatures and nuances of namespaces.For this, you are referred to a <tt>C++</tt> book.<p><h3>Namespaces and NTL</h3><p>In ISO mode, the standard library is "wrapped" in namespace <tt>std</tt>,and NTL is "wrapped" in namespace <tt>NTL</tt>.Thus, the header file <tt><NTL/ZZ.h></tt> in ISO mode lookssomething like this:<pre>namespace NTL { // ... class ZZ { /* ... */ }; // ... ZZ operator+(const ZZ& a, const ZZ& b); ZZ operator*(const ZZ& a, const ZZ& b); std::istream& operator>>(std::istream& s, ZZ& x); std::ostream& operator<<(std::ostream& s, const ZZ& a); // ... }</pre>Therefore, one must explicitly qualify all names, or use appropriateusing directives.Here is how one could write the <a href="tour-ex1.html">first example</a> of the tour inISO mode.<pre>#include <NTL/ZZ.h>int main(){ NTL::ZZ a, b, c; std::cin >> a; std::cin >> b; c = (a+1)*(b+1); std::cout << c << "\n";}</pre><p>Notice how everything is explicitly qualified.Actually, the input/output operators <tt><<</tt> and <tt>>></tt>,and the arithmetic operators <tt>+</tt> and <tt>*</tt> are not explicitlyqualified, but rather, the compiler finds them through a gimmickcalled <i>Koenig Lookup</i>, which will look for functions (and operators)declared in namespace <tt>NTL</tt>, because the type of the argument(<tt>ZZ</tt>) is a class declared in that namespace.<p>Even with Koenig Lookup, explicit qualification canbe a bit tedious.Here is the same example, this time with using directives.<pre>#include <NTL/ZZ.h>using namespace NTL;using namespace std;int main(){ ZZ a, b, c; cin >> a; cin >> b; c = (a+1)*(b+1); cout << c << "\n";}</pre>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -