15 Programming Language Concepts Using C and C++_Parameterized Types - Wikibooks, open books for an open world.pdf

Embed Size (px)

Citation preview

  • 8/10/2019 15 Programming Language Concepts Using C and C++_Parameterized Types - Wikibooks, open books for an ope

    1/33

    Programming Language Concepts Using C and

    C++/Parameterized Types

    Achieving reuse through inheritance may at times lead to an explosion in the number of classes. Consider defining stacks of

    different types. Using the inheritance approach, we would start out with defining an abstract class containing the attributes

    common to all stacks and get people to derive their specialized stack classes from this class. Problem with this approach issince

    operation signatures are type dependentnot much can be reused.

    cl ass Abst r act St ack { vi rt ual bool empt y( voi d) const = 0;} / / end of cl ass Abst r actSt ack

    cl ass St dnt St k : publ i c Abst ractSt ack {publ i c: bool peek( Student&) const ; bool pop( Student &) ; voi d push( Student) ;

    vi rt ual bool empt y( voi d) const ; . . .pri vat e: . . .} / / end of cl ass St dnt St k

    A stack of Shapeobjects using a similar implementation technique would mean all occurrences of Student must be replacedwith Shape, which leaves very little room for reuse. Way out of this is defining a stack of something that can be interpreted as astack of anything. In C/C++, that something is voi d* ; in Java and C#, it is the root class Obj ect .

    Example: Genericness in pre-1.5 Java.

    public interface I St ack { public Obj ect peek( ) throws StackEmpty; public Obj ect pop( ) throws StackEmpty; public void push( Obj ect newI t em) ; publicboolean i sEmpt y( ) ;} // end of interface IStack

    public class Gener i cSt ack implements I St ack { public Obj ect peek( ) throws St ackEmpty { . . . } public Obj ect pop( ) throws StackEmpty { . . . } public void push( Obj ect newI t em) { . . . } publicboolean i sEmpt y( ) { . . . }

    . . . . . .} // end of class GenericStack

    In this pre-1.5 Java implementation we can create and use stacks of various types without having to rewrite the functionality in

    different classes. This solution has a serious flaw, though. Users of Generi cSt ackare responsible for correct use of the class.Errors such as pushing a Shapeonto a stack of Students are tolerated by the compiler and cannot be caught before run-time.After all, both classes are derived from Obj ect and their objects are in that aspect alike.

    So we need to take another step for achieving reuse without sacrificing type safety. The answer is provided by introducing a new

    feature into the language:parameterized types. Using parameterized types we can get higher levels of reuse by collapsing a base

    class and a number of derived classes into a single class without compromising type safety. Instead of having an abstract class and

    various specialized classes deriving from this abstract class, we now have a single parameterized class.

    Example: Generic classes in Java.

    gramming Language Concepts Using C and C++/Parameterized Types... http://en.wikibooks.org/wiki/Programming_Language_Concepts_Using...

    33 20-11-2014 13:08

  • 8/10/2019 15 Programming Language Concepts Using C and C++_Parameterized Types - Wikibooks, open books for an ope

    2/33

    public interface I St ack { public V peek( ) throws StackEmpt y; public V pop( ) throws StackEmpty; public void push( V newI t em) ; publicboolean i sEmpt y( ) ;} // end of interface IStack

    public class St ack implements I St ack {

    public V peek( ) throws St ackEmpt y { . . . } public V pop( ) throws StackEmpty { . . . } public void push( V newI t em) { . . . } publicboolean i sEmpt y( ) { . . . } . . . . . .} // end of class Stack

    Replacing inheritance in the first scenario with parameterized types in the final scenario might make you think parameterized

    types and inheritance are alternatives to each other. That would be wrong, though. These two features are actually complementary

    reuse tools: while inheritance is used to express the is-a relation between classes found at different levels of the class hierarchy,

    parameterized types are used to group classes found at the same level. In other words, inheritancesince it adds a new levelis"vertical", whereas parameterized typessince they work by collapsing classes at the same levelare "horizontal".

    Compl ex I magi nary I nt eger Natur al Rat i onal Real Compl exVect or, I nt eger Vect or , Real Vect or, . . . . . .

    Without inheritance and parameterized types we have a collection of types that can be related to each other with compositionand association.

    Obj ect Compl ex Real Rat i onal I nt eger Natural I magi nar y Vector

    Thanks to inheritance [and polymorphism] we organize these types into a hierarchy that better reflects our perception of them.

    After all, aren't real numbers actually complex numbers with no imaginary part? Aren't rational numbers real numbers that can be

    expressed as the ratio of two integers? ... This is further strengthened by the use of parameterized types. In math, we never speak

    of vectors with different content type as different concepts; there is only one definition for vector.

    Note that the use of a collection type in the previous presentation is not by chance. Genericness is generally regarded as

    parameterization of collection types. But many times we need to reuse the functionality of a single function working on a

    parameterized type. Generic algorithmssuch as accumul ate, count _i f, f or _each, i nner_product , mi n_el ement ,r andom_shuf f l e, and so onimplemented as part of the standard library are examples to this.

    Contents1 Template Compilation Models

    1.1 Separation Compilation Model

    1.2 Inclusion Compilation Model

    gramming Language Concepts Using C and C++/Parameterized Types... http://en.wikibooks.org/wiki/Programming_Language_Concepts_Using...

    33 20-11-2014 13:08

  • 8/10/2019 15 Programming Language Concepts Using C and C++_Parameterized Types - Wikibooks, open books for an ope

    3/33

    2 Interface / Implementation

    2.1 Test Program

    3 Container Types

    3.1 Sequences (Linear Containers)

    3.1.1 Container Adapters3.2 Associative (Non-linear) Containers

    3.3 Generic Functions in STL

    4 Function Objects

    4.1 Interface

    4.2 Implementation5 Test Program

    5.1 Running the Test Program

    6 Predefined Function Objects

    6.1 Arithmetic Function Objects

    6.2 Relational Function Objects

    6.3 Logical Function Objects7 Simulating Local Functions

    8 Notes

    Template Compilation Models

    Once a parametric type is implemented it is typically used by indefinitely many clients. This means the same module will have to

    be re-used to create objects of indefinitely many types. Well, not really! At least not so in the C++ world.

    Separation Compilation Model

    In the separation compilation model, template file is compiled and this compiled file is supplied to the clients. Given the diversity

    of object file formats and instruction sets, for a language like C++ this seems to be a rather e lusive option.

    A first attempt at solving this problem dictates the implementer to maintain a separate object module for each platform. Given the

    possibility of multiple platforms coexisting in the same company or clients willing to switch to/add a new platform, this option

    turns out to be a maintenance nightmare.

    Interoperability between various platforms is made possible by adapting a common file format and compiling the source module

    into intermediate code. This scheme is used by languages like Java and C#, where the clients, regardless of the platform, use

    intermediate code equivalent of the source module. Needless to say this technique is not well-suited to C++. Therefore the

    separation compilation model is not widely implemented by C++ compilers.

    With the separation compilation model, the class template definition and the definitions of its inline member functions are placed

    in a header file, whereas the definitions of the member functions that are not inline and static data members are placed in a

    program text file. With this model, the definitions for a class template and its members are organized in the same way we organize

    the definitions of non-template classes and their members.

    In an environment where the separation compilation model is supported, we need to make some changes in our code.

    Example: C++ code a la separation compilation model.

    StackTemplate

    gramming Language Concepts Using C and C++/Parameterized Types... http://en.wikibooks.org/wiki/Programming_Language_Concepts_Using...

    33 20-11-2014 13:08

  • 8/10/2019 15 Programming Language Concepts Using C and C++_Parameterized Types - Wikibooks, open books for an ope

    4/33

    expor t t empl ate cl ass Stack { f r i end . . .publ i c: . . .pr i vat e: . . .}; / / end of cl ass Stack

    Implementation of member function definitions that are not inline are moved into a file named, say StackTemplate.cxx.

    You may choose to use a more selective version of the export keyword.

    Example: Selective export.

    StackTemplate

    t empl ate cl ass Stack {f r i end . . .publ i c:

    . . .pr i vat e: . . .}; / / end of cl ass Stack

    t empl ate bool St ack: :empt y( voi d) {. . . }. . .

    StackTemplate.cxx

    expor t t empl ate bool St ack: :peek(Type& val ue) {. . . }

    expor t t empl ate bool St ack: :pop (Type& val ue) {. . . }

    expor t t empl atevoi d St ack: :push(Type val ue) {. . . }

    Inclusion Compilation Model

    In the inclusion compilation model, the definition of the member functions and static members of class templates must be included

    in every file in which they are instantiated.

    Definition: The act of using a parameterized type is called instantiation.

    There are some drawbacks in providing the definitions for the members of a class template in a header file. The member function

    definitions may be quite large and may describe implementation details that the user may want to ignore or that we, as

    implementers, may want to hide from our users. Moreover, compiling the same template definitions across multiple files can add

    to the compile-time of our programs unnecessarily. The separation compilation model, if available, allows us to separate the class

    template interface (that is, the class template definition) from its implementation (that is, the definitions of its member functions

    and static data members).

    Interface / Implementation

    StackTemplate

    gramming Language Concepts Using C and C++/Parameterized Types... http://en.wikibooks.org/wiki/Programming_Language_Concepts_Using...

    33 20-11-2014 13:08

  • 8/10/2019 15 Programming Language Concepts Using C and C++_Parameterized Types - Wikibooks, open books for an ope

    5/33

    #i f ndef STACKTEMPLATE_ HXX1.

    #def i ne STACKTEMPLATE_ HXX2.

    3.

    #i ncl ude 4.

    #i ncl ude 5.

    #i ncl ude 6.

    usi ng namespace st d;7.

    8.

    namespace CSE224 {9.

    namespace DS {10.

    Here is where we begin the definition of our class template. The list surrounded by includes the template parameter

    list, which can have a combination of type parameters and non-type parameters.

    A template type parameter consists of the keyword cl assor the keyword t ypenamefollowed by an identifier. In a templateparameter list, both keywords have the same meaning. They indicate that the parameter name that follows represents a built-in or

    user-defined type. In this case, our single parameter represents the type of information held in the stack.

    A template non-type parameter consists of an ordinary parameter declaration. A non-type parameter indicates that the parameter

    name represents a potential value. This value represents a constant in the class template definition.

    Example: A generic buffer containing as many as a given number of objects.

    t empl ate cl ass Buf f er ; . . . Buf f er buf; / / A buf f er of 5 i nt s.

    t empl at e 11.

    c l ass Stack {12.

    Notice the explicit template argument following the function name. This syntax is used to specify that the f r i enddeclarationrefers to an instantiation of the function template. That is, there is a one-to-one mapping between the instantiations of the class

    template and its friend. In our case, the only friend of St ackis operat or

  • 8/10/2019 15 Programming Language Concepts Using C and C++_Parameterized Types - Wikibooks, open books for an ope

    6/33

    f r i end voi d f unct i onName( For mal - Par- Li s t) ; . . .};

    declares functionName to be friend to all Cl assNameinstantiations.

    One-to-many: For each instantiation of the class template, all instantiations of friend class/functions are friends. For

    example,

    t empl ate cl ass Cl assName { t empl ate f r i end voi d f unct i onName( . . . , P a r , . . . ) ;

    . . .};

    declares all instantiations of functionName to be friends to each instantiation of Cl assName.

    f r i end ostream& oper ator

  • 8/10/2019 15 Programming Language Concepts Using C and C++_Parameterized Types - Wikibooks, open books for an ope

    7/33

    parameter the first two declare call-by-reference parameters. Because we do not have such a requirement the last function, on the

    other hand, declares a call-by-value parameter. As is explained in the Object-Based Programming chapter, this could also be

    accomplished by the following declaration.

    voi d push( const I t emType&) ;

    bool peek( I t emType ) ;17.

    bool pop( I t emType ) ;18.

    vo id push( I t emType) ;19.

    bool empt y( voi d) ;20.

    21.

    pr i vate:22.

    vect or is one of the abstract container types provided by the C++ standard library. Like an array, it holds an ordered collectionof elements of a single type. It is represented in a contiguous area of memory, which makes random access possible. Unlike an

    array, however, size of a vect or can grow dynamically. When the vect or needs to grow itself, it allocates additional storagecapacity beyond its immediate needit holds this storage in reserve. You can try the following to see how a vector grows in your

    system.

    Vector_Growth.cxx

    #i ncl ude #i ncl ude

    usi ng namespace st d;

    i nt mai n( voi d) { i nt cap; vect or vec;

    cout

  • 8/10/2019 15 Programming Language Concepts Using C and C++_Parameterized Types - Wikibooks, open books for an ope

    8/33

    vect or I t emType> _st ack;23.

    }; / / end of cl ass Stack24.

    Whoops! What have we got here? Definition of a class member function inside a header file?!. It certainly goes against the

    information hiding principle! Unfortunately, we cannot avoid it in this case. This is a consequence of the way templates are

    supported by C++ compilers. For more on this, check the Template Compilation Models section.

    t empl at e 26.

    bool Stack: :27.

    peek(Type val ue) {

    28.

    i f ( empt y( ) ) return f a l s e;29.

    Sometimes we want the user of a container data type to be able to access, one at a time, each and every component in the

    container. For an array, it would be very simple: start from the first component and each time you want to move on to the next

    component proceed by increasing the index value by one; for a linked list all you have to do is to follow the link to the next

    component; for a sequential file issuing a read operation will do the job. Although the way you achieve is different the idea of

    traversing an ADT is an abstract operation common to many of them. In object-oriented programming languages such an

    operation is provided by means of iterators.[1]

    Definition: An iteratoris an auxiliary data structure created with the sole purpose of permitting access to the values in a container

    through a sequence of simple operations, while hiding from the user of the iterator the actual implementation of these operators.

    In C++, an iterator is defined to be a "pointer" to the components data type. begi n( ) and end( ) are used to locate thebeginning and end of the container, respectively. Along with an iterator used to traverse the container in the forward direction,

    one can also have a reverse iterator, an iterator that starts traversal from the last component and moves toward the beginning. For

    such an iterator, r begi n( ) and r end( ) methods are used to locate the two ends of the container.

    Insert iterator figure here

    For a forward iterator, ++accesses the next element in the container, while it accesses the previous component in the case of areverse iterator. Using *to dereference the iterator yields the contents of component currently being visited. (Do not forget thatthe iterator is in fact a pointer!)

    Next line defines a reverse iterator on the vect or and sets it to point to the last component.

    vector : : reverse_ i terat or i t er = _st ack. r begi n( ) ;31.

    val ue = * i t er ; 32.

    33.

    return( t rue) ;34.

    } / / end of bool Stack: : peek( Type&)35.

    gramming Language Concepts Using C and C++/Parameterized Types... http://en.wikibooks.org/wiki/Programming_Language_Concepts_Using...

    33 20-11-2014 13:08

  • 8/10/2019 15 Programming Language Concepts Using C and C++_Parameterized Types - Wikibooks, open books for an ope

    9/33

    Each and every class template member function definition must be preceded by the t empl atekeyword and the templateparameter list.

    Parameter names stay in scope throughout the definition of the following class or the member function. Thats why we can use

    different names for the same parameter.

    t empl at e 37.

    bool St ac k T>: :38.

    pop(T& val ue) {39.

    i f ( empt y( ) ) return f a l s e;40.

    41.

    vect or T : : rever se_ i terator i t er = _stack. rbegi n( ) ;42.

    val ue = * i t er ; 43.

    _s t ack. pop_back( ) ;44.

    45.

    return( t rue) ;46.

    } / / end of bool Stack: : pop(T&)47.

    48.

    templ ate c l ass Type>49.

    vo id Stack Type>: :50.

    push(Type val ue) { _st ack. push_back( val ue) ; }51.

    52.

    t empl at e 53.

    bool Stack Type>: :54.

    empt y( voi d) { return(_ st ack . empt y( ) ) ; }

    55.

    56.

    t empl at e 57.

    os t r ea oper at o r< ( ost r ea os, const St ack r hs) {58.

    os

  • 8/10/2019 15 Programming Language Concepts Using C and C++_Parameterized Types - Wikibooks, open books for an ope

    10/33

    vector Type>: : const_ i terator i t er = rhs. _stack. begi n( ) ;60.

    vect or: : const_ i terator i end = rhs. _stack. end( ) ;61.

    62.

    i f ( i t er == i end) {63.

    cout

  • 8/10/2019 15 Programming Language Concepts Using C and C++_Parameterized Types - Wikibooks, open books for an ope

    11/33

    8.

    i nt mai n( voi d) {9.

    Next two lines are examples to instantiation of our class template. As a result of elaborating these statements compiler, or the

    compiler-linker pair, will synthesize code required for two classes. In order to convince yourself about this add lines that definesand uses a stack of a different type and observe the increase in size of the resulting executable.

    Stack

  • 8/10/2019 15 Programming Language Concepts Using C and C++_Parameterized Types - Wikibooks, open books for an ope

    12/33

    Compl ex cval ;36.

    cstack. pop( cval ) ;37.

    dstack. pop( dval ) ;38.

    } / / end of f or ( d = 1; d

  • 8/10/2019 15 Programming Language Concepts Using C and C++_Parameterized Types - Wikibooks, open books for an ope

    13/33

    seq. i nsert ( seq. end( ) , val ) seq.push_back( val ) seq. i nsert ( seq. begi n( ) , val ) seq.push_f r ont( val ) seq. erase( - - seq. end( ) ) seq.pop_back( ) seq. erase( seq. begi n( ) ) seq.pop_f ront ( )

    Given the cost of item insertion/removal due to shifting, it is no surprise that vect or does not support pop_f r ont andpush_f r ont .

    The two ends of the sequence are accessed by means of the backand f r ont functions.

    Sequence types and their operations

    Operation deque l i st vector

    assi gn, swap

    at , [ ]

    back, f r ont

    begi n, end, r begi n, r end

    capaci t y, reserve

    cl ear

    empt y

    er ase

    i nsert

    max_si ze, resi ze, si ze

    mer ge

    pop_back, push_back

    pop_f r ont , push_f r ont

    remove, r emove_i f

    reverse sort

    spl i ce

    uni que

    Observe that the container-specific functions reflect the nature of the underlying sequence. Thanks to their random-access

    support both vect or and dequehave functions, at and [ ] , for accessing elements using index values. Since l i s t and dequeincrease their size by one as new items are inserted, neither supports capacity and reserve.

    Signatures of the l i s t -specific functions along with what they do are given below. Wherever required bi n_pr ed, a binarypredicate, is used in determining the ordering criterion utilized in the algorithm.

    l s t . mer ge( sec_l st ) & l s t . mer ge( sec_l st , bi n_pr ed) : Merges sec_l st into the list, both of which aresorted. If not given ordering is done by

  • 8/10/2019 15 Programming Language Concepts Using C and C++_Parameterized Types - Wikibooks, open books for an ope

    14/33

    Operation pr i ori t y_queue queue st ack

    back

    empt y

    f r ont

    pop

    push

    si ze

    t op

    Associative (Non-linear) Containers

    STL supports two types of associative containers: mapand set . The former is used as a fast lookup structure relating a key witha value, whereas the latter is used to implement the mathematical notion of sorted sets.

    Neither container type allows duplicates: it is not possible to relate a particular key with more than one value; a set cannot contain

    more than one copy of an object. In case duplicates are required one should use multimap and multiset, which are map and set

    with the no-duplicates criterion removed.

    Operation map set

    [ ]

    begi n, end, r begi n, r end

    cl ear

    count

    empt y

    equal _r ange

    erase

    f i nd

    i nser t

    key_comp, val ue_comp

    l ower_bound, upper_bound

    max_si ze, si ze

    swap

    Fundamental operations supported are i nsert , erase, and f i nd.

    map. i nsert ( pai r ) & set. i nser t ( val ) : Inserts key-value pai r /val only if it does not exist in the map/set . Thisfunction returns an iterator-success pair, where the iterator part indicates the location of insertion and the success partdescribes whether the operation has successfully been inserted or not.

    assoc_cnt nr . i nser t ( s t_ i t r , end_i t r ) : Inserts all items found in [st _ i t r , end_i t r ).map. i nsert ( i t r , pai r ) & set. i nser t ( i t r , val ) : Inserts pai r /val after the location indicated by i t r andreturns an iterator to the item just inserted. Note the location of insertion passed is just a suggestion.

    assoc_cnt nr . erase( i t r ) : Erases the element indicated by i t r .assoc_cnt nr . erase( st_ i t r , end_ i t r ) : Erases all elements in the range between st _ i t r and end_i t r .map. erase( key) & set . er ase( val ) : Erases all elements that have the value key/val . This function returns thenumber of entries deleted, which can be zero or one in a mapor set whereas in a mul t i mapor mul t i set it can bemore than one.

    map. f i nd( key) & set. f i nd( val ) : Returns an iterator to the related entry in the map/set if it exists. Otherwise, itreturns an iterator to the end of the container.

    As in the vect or and dequeclasses one can also use the subscript operator ([ ] ) for finding and inserting an entry in a map.One should however be aware of the differences. First of all, both insert and find provide means for flagging unsuccessful

    operations. As a result of looking up a non-existing key in the map, f i ndreturns an iterator to the end of the mapwithout making

    gramming Language Concepts Using C and C++/Parameterized Types... http://en.wikibooks.org/wiki/Programming_Language_Concepts_Using...

    f 33 20-11-2014 13:08

  • 8/10/2019 15 Programming Language Concepts Using C and C++_Parameterized Types - Wikibooks, open books for an ope

    15/33

    any modification in the map, whereas [ ] makes an entry relating the key with a default value. Also, thanks to the second version,i nsert enables multiple entries to be inserted in a single application of the function while this is limited to one in the case of [ ] .

    Example: Fundamental operations on maps.

    #i ncl ude #i ncl ude . . .. . .

    pai r i ni t i al _ent r i es[ ] = { make_pai r ( "bi l gi sayar ", "comput er ") , make_pai r ( "donani m", "hardware") , make_pai r ( "yazi l i m", "sof t war e" ) }; st r i ng wor ds[ ] = {"komutsal " , "yordamsal ", "bi r i msel " , "nesne- t emel l i " , "nesne-yonel i ml i "}; st r i ng meani ngs[ ] = {"i mperat i ve" , "procedural ", "modul ar", "obj ect - based","obj ect - or i ent ed"};

    Next line creates a mapand initializes it with the contents of the array named i ni t i al _entr i es.

    map par _di ct ( i ni t i al _entr i es, i ni t i al _ent r i es + 3) ;

    Next f or -loop populates the mapwith five more entries.

    f or ( i nt i = 0; i < 5; i ++) par _di ct [ wor ds[ i ] ] = meani ngs[ i ] ;

    Next line attempts to insert an already existing key, which causes the value in the second part of the pair returned from

    insert to set to f al se.

    pai r resul t = par _di ct. i nser t ( map: : val ue_t ype( wor ds[ 4] , meani ngs[ 4] ) ) ; i f ( ! r esul t . second)

    cout

  • 8/10/2019 15 Programming Language Concepts Using C and C++_Parameterized Types - Wikibooks, open books for an ope

    16/33

    par_ di ct. er ase( searched_word) ; . . .

    Other operations applicable on an associative container include the following.

    assoc_cnt nr . count ( key/ val ) : Returns the number of occurrences of key/val as the key part of the entriesin the mapor in the set .assoc_cnt nr . equal _r ange( key/ val ) : Returns a pair of iterators that has keyas its part of the key-value

    pair or val as the element value.assoc_cnt nr . l ower_bound( key/ val ) & assoc_cnt nr . upper_bound( key/ val ) : Returns an iteratorto the smallest value that is greater-or-equal to (greater than) key/val .

    Generic Functions in STL

    Strength of the seemingly thin interface offered by different container types is augmented by the use of generic functions

    of STL. These functions make heavy use of iterators for expressing the boundaries of the container. Instead of

    accumul ate( cont ai ner , i ni t _val ) , which would sum up the elements of cont ai ner , we haveaccumul ate( st _i t r , end_ i t r , i ni t_val ) , which sums up the elements in [st _ i t r , end_i t r ). The secondversion is more flexible in that it enables us to apply the generic function not only on the whole container but also on a part

    of it. In some functions, further specialization can be provided by passing a function object to be applied on the elements

    of the container.

    Example: Applying a generic function on a part of a container.

    Inclusion of al gori t hmand numer i care required for accumul ate. f unct i onal is required for multiplies.

    #i ncl ude #i ncl ude #i ncl ude . . .

    i nt i nt _arr [ ] = {- 1, 1, 3 , 5, 7, 9, 11}; i nt i nt _vec( i nt _arr , i nt_arr + 7) ;

    Next line sums up all elements, except for the first and the last, of i nt _arr and stores the result in sum.

    i nt sum= accumul ate( i nt_arr + 1, i nt _ar r + 6, 0) ;

    Next application of accumul atefinds the product of all elements in i nt _vec.

    i nt product = accumul ate( i nt _vec. begi n( ) , i nt _vec. end( ) , 1,mul t i pl i es( ) ) ; . . .

    A helpful hint in dealing with the complexity of the generic functions in STL is the naming of functions that take

    predicates. For instance, count ( st_ i tr , end_i tr , val ) returns the number of elements in [st _ i t r , end_i t r )equal to val . Conditional form of this function, count _i f( st _ i t r , end_i t r , pred) , basically does the samething: it returns the number of elements in [s t _ i t r , end_i t r ) that satisfy pr ed. Other functions that come with aconditional form are given below.

    f i nd( st_ i tr , end_i t r , val ) : Returns an iterator for the first occurrence of val in the range delimited byst _ i t r and end_i t r . If val is not found end_i t r is returned.r emove( st_ i tr , end_i t r , val ) : Removes all elements in [st _ i t r , end_i t r ) that are equal to val .Note neither versionsthat is, r emoveand remove_i fdo any actual deletion from the underlying container. Aselements that do not satisfy the (explicitly or implicitly stated) criterion are seen, they are moved to the front of the

    current container. Any actual deletion is meant to take place upon application of an erasefollowing either one ofr emoveor r emove_i f. Both functions return an iterator to a position that comes as many as the number of

    removed elements before the end.Example: Peculiarity of removeand remove_if.

    . . . i nt i nt _arr [ ] = {- 1, 1, 3, 5, 1, 9, 11};

    gramming Language Concepts Using C and C++/Parameterized Types... http://en.wikibooks.org/wiki/Programming_Language_Concepts_Using...

    f 33 20-11-2014 13:08

  • 8/10/2019 15 Programming Language Concepts Using C and C++_Parameterized Types - Wikibooks, open books for an ope

    17/33

    vect or i nt _vec( i nt_arr , i nt _arr + 7) ;

    Next line "removes" all elements in i nt _vecthat are equal to 1. Upon execution of r emove, i nt _vecwill have{- 1, 3, 5, 9, 11, 9, 11}as its content. The returned iterator will be pointing at the second 9. In order toactually complete the deletion, we must execute an erase.

    vect or: : i t er ator fi r st_one = remove( i nt _vec. begi n( ) , i nt _vec. end( ) , 1) ; i nt _vec. er ase( f i r st_one, i nt _vec. end( ) ) ;

    l i s t i nt _l i st ( i nt _ar r , i nt_ar r + 7) ;

    l i s t : : i t er at or f i rst_ l ess5 = remove_i f( i nt _l i st . begi n( ) , i nt _l i st . end( ) , bi nd2nd( l ess( ) , 5) ) ; i nt _l i st . erase( f i r st _ l ess5, i nt _ l i st . end( ) ) ; . . .

    r epl ace( st_i t r, end_i t r, val , new_val ) : Repl aces al l occur r ences of val i n[ st_ i t r , end_ i t r ) wi t h new_val .

    Another useful way to figure out more about generic functions in STL is to spot those functions that work their magic on a

    copy of the original container. Such functions have copysomewhere in their names. For instance, r emove_copymovesthose values in the original container that do not satisfy the stated criterion to another container and returns an iterator to

    the end of the resulting container. Other functions working in a similar fashion include r emove_copy_i f,r epl ace_copy, r epl ace_copy_i f, r ever se& r everse_copy, rotate& rot at e_copy, and uni que&uni que_copy.

    Example: Copying functions.

    . . . vect or copy_vec; copy_vec. r esi ze( 5) ; remove_copy( i nt _vec. begi n( ) , i nt _vec. end( ) , copy_vec. begi n( ) , 1) ;

    l i s t copy_l i st ; copy_l i st. resi ze( 3) ; r emove_copy_i f( i nt _l i st . begi n( ) , i nt _l i st . end( ) , copy_l i st. begi n( ) ,bi nd2nd( l ess( ) , 5) ) ; . . .

    One other group of functions involve generalizations of certain container-specific functions. For instance, while

    l st . mer ge( sec_l st ) & l s t . mer ge( sec_l st , bi n_pred) merges two sorted lists, generic function mer gemerges any two sorted containers. Other functions in this group include count , equal _r ange, l ower_bound,upper_bound, mer ge, r emove, r emove_i f, reverse, sort , swap, and uni que.

    Example: Using the generalized versions of container-specific functions.

    . . . i nt i nt _arr [ ] = {2, - 1, 2, - 2, 2, - 3}; vect or i nt _vec( i nt_arr , i nt _arr + 6) ;

    If - 1occurs in i nt _vec, next two lines insert 0right before the first occurrence of -1. Otherwise, ois inserted atthe end of i nt _vec.

    vect or: : i t er ator fi r st_one = f i nd( i nt _vec. begi n( ) , i nt _vec. end( ) , - 1) ; i nt _vec. i nsert ( f i rst_one, 0) ;

    The following definition create a list using the contents of the vect or in reverse order.

    l i st i nt _l i st ( i nt _vec. rbegi n( ) , i nt _vec. r end( ) ) ;

    gramming Language Concepts Using C and C++/Parameterized Types... http://en.wikibooks.org/wiki/Programming_Language_Concepts_Using...

    f 33 20-11-2014 13:08

  • 8/10/2019 15 Programming Language Concepts Using C and C++_Parameterized Types - Wikibooks, open books for an ope

    18/33

    Next three lines delete all items in between the first and second occurrences of 2, including the 2's. Noticesincethere is no random access supportunlike in vect ors and deques, we cannot use iterator arithmetic [that is, wecannot use + and -] while using list iterators. Hence is the use of - - following a ++.

    l i st : : i t er at or f i rst _two = f i nd( i nt _vec. begi n( ) , i nt _vec. end( ) , 2) ; l i st : : i t er at or second_t wo = f i nd( ++f i rst _two, i nt _vec. end( ) , 2) ; i nt _vec. er ase( - - f i rst_t wo, ++second_t wo) ;

    Next three lines find the third smallest item in a deque created from a previously created list. Note we can now use

    iterator arithmetic.

    deque i nt _deque( i nt _ l i st . begi n( ) , i nt _l i st . end( ) ) ; sort ( i nt_deque. begi n( ) , i nt _deque. end( ) ) ; i nt t hi r d_smal l est = *( i nt_deque. begi n( ) + 2) ;

    Next four lines merge two sorted sequences into a single one. Observe that the resulting sorted sequence is

    populated starting from its end. Note also the list, initially created empty, is later resized to take as many as one

    more than the total number of elements. In the process, each slot is initialized to - 100.

    l i st merged_l i st ; merged_l i st . resi ze( i nt _deque. si ze( ) + i nt _vec. si ze( ) + 1, - 100) ;

    sort ( i nt _vec. begi n( ) , i nt _vec. end( ) ) ; mer ge( i nt _deque. begi n( ) , i nt _deque. end( ) , i nt _vec. begi n( ) , i nt _vec. end( ) ,merged_l i st . rbegi n( ) ) ; . . .

    Yet another group comprises the classical higher-order functions: accumul ate, f i nd, f or_each, and transform.These functions do the equivalent of r educe, f i l t er , f or each, and mapfunctions provided in functionalprogramming languages.

    Example:

    . . . i nt i nt _arr [ ] = {0, 1, 2, 3, 4, 5}; l i st i nt _l i st ( i nt _ar r , i nt_ar r + 6) ;

    voi d dump_el ement ( i nt el mt ) { cout

  • 8/10/2019 15 Programming Language Concepts Using C and C++_Parameterized Types - Wikibooks, open books for an ope

    19/33

    Given a containersay [first, last)with the heap property, pop_heapswaps the first and last items in the containerand reorganizes [first, last-1), by means of downheaping, so as to preserve the heap property for [first, last-1).

    Similarly,given a containersay [first, last)whose subsequence [first, last-1) has the heap property, push_heapinsertsthe item in position last-1 into the container by means of upheaping, so that we get the whole container to satisfy the heap

    property.

    Function Objects

    An intuitive notion lacking in C++, like almost any other imperative language, is the t reatment of functions as first-classvalues. It's not possible to pass around and return functions; one must resort to using pointer-to-functions, instead. This

    section offers an alternative solution to this by introducing function objects, objects that look like functions. Instead of

    using functions we use instances of a class that overloads the function call operator.

    Definition: Afunction objectis an instance of a class that overloads the function call operator. Function call operator

    encapsulates what normally would be encapsulated as a function.

    Following a selection of standard function objects supported by C++, we provide an application of the concept in

    simulating local functions.

    Interface

    Polynomial

    #i f ndef POLYNOMI AL_HXX1.

    #def i ne POLYNOMI AL_HXX2.

    3.

    #i ncl ude

  • 8/10/2019 15 Programming Language Concepts Using C and C++_Parameterized Types - Wikibooks, open books for an ope

    20/33

    This [implicit conversion] takes away our freedom of ordering the arguments sent to the constructor. Say, we change its

    semantics so that the first parameter stands for the coefficient of the second-degree component, the second the coefficient

    of the first-degree component and the last the constant. This arrangement has a rather unexpected consequence. Take a

    look at the following C++ fragment:

    . . . Pol ynomi al c; . . . c = 3. 0; / / 1

    . . .

    The doubl evalue 3. 0is converted to a Pol ynomi al using the relevant constructor and 3x 2will be assigned to c.Very unlikely what we really wanted!

    / / Pol ynomi al ( const Pol ynomi al & exi st i ng_pol ) ; / / ~Pol ynomi al ( voi d) ; / / Pol ynomi al & operat or=( const Pol ynomi al &) ;

    Given the above explanations, one may think that the following f r i enddeclaration is superfluous. Well, not really!Because the object the message is sent to is not implicitly converted.

    f r i end bool operat or==( doubl e, Pol ynomi al ) ;15.

    bool operat or==( const Pol ynomi al &) ;16.

    Next line is a declaration that will make Pol ynomi al objects look like functions, which will give an illusion of functionsbeing treated as first-class citizens. This is achieved through overloading the function call operator.

    doubl e oper ator ( ) ( doubl e x) ;18.

    Thanks to the implicit conversion mentioned above, we no longer have to have three functions to overload the +operator;two will be enough.

    Pol ynomi al operat or ( const Pol ynomi al ) ; 20.

    f r i end Pol ynomi al operat or ( doubl e, Pol ynomi al ) ;21.

    Pol ynomi al & operat or+=( const Pol ynomi al &) ;22.

    23.

    Pol ynomi al operat or - ( const Pol ynomi al ) ;24.

    f r i end Pol ynomi al operat or - ( doubl e, Pol ynomi al ) ;25.

    Pol ynomi al & operat or - =( const Pol ynomi al &) ;26.

    27.

    pr i vate:28.

    doubl e _ sec , _ f i r , _ con;29.

    gramming Language Concepts Using C and C++/Parameterized Types... http://en.wikibooks.org/wiki/Programming_Language_Concepts_Using...

    f 33 20-11-2014 13:08

  • 8/10/2019 15 Programming Language Concepts Using C and C++_Parameterized Types - Wikibooks, open books for an ope

    21/33

    }; / / end of cl ass Pol ynomi al30.

    } / / end of namespace Mat h31.

    } / / end of namespace CSE22432.

    #endi f33.

    Implementation

    Polynomial.cxx

    #i ncl ude "mat h/ Pol ynomi al "1.

    2.

    namespace CSE224 {

    3.

    namespace Mat h {4.

    This is what makes instances of Pol ynomi al function objects: operator( ) is overloaded to return the value of thepolynomial at a given point.

    doubl e Pol ynomi al : :5.

    operat or ( ) ( doubl e x) {6.

    return(_ sec * x * x _ f i r * x _con) ;7.

    } / / end of doubl e Pol ynomi al : : operator( ) ( const doubl e)8.

    9.

    bool Pol ynomi al : :10.

    operat or==( const Pol ynomi al & r hs) {11.

    i f (_s ec ! = rhs._ sec) return f a l s e;12.

    el s e i f (_ f i r ! = r hs. _ f i r ) return f a l s e;13.

    el s e i f (_con ! = rhs. _con) return f a l s e;14.

    el se return t r ue;15.

    } / / end of equal i t y-t est operator16.

    17.

    bool operat or==( doubl e l hs, Pol ynomi al & r hs) {18.

    return( r hs. _sec == 0 && r hs. _ f i r == 0 && rhs. _con == l hs) ;19.

    } / / end of bool operat or==( doubl e, Pol ynomi al &)20.

    21.

    gramming Language Concepts Using C and C++/Parameterized Types... http://en.wikibooks.org/wiki/Programming_Language_Concepts_Using...

    f 33 20-11-2014 13:08

  • 8/10/2019 15 Programming Language Concepts Using C and C++_Parameterized Types - Wikibooks, open books for an ope

    22/33

    Pol ynomi al Pol ynomi al : :22.

    operat or ( const Pol ynomi al rhs) {23.

    Pol ynomi al r es_pol ;24.

    25.

    res_pol . _sec =_s ec + rhs. _sec;26.

    r es _pol . _ f i r =_f i r r hs. _f i r ;27.

    res_pol . _con =_c on r hs. _con;28.

    29.

    return r es_pol ;30.

    } / / end of Pol ynomi al Pol ynomi al : : operator +( const Pol ynomi al )31.

    32.

    Pol ynomi al operat or+( doubl e l hs, Pol ynomi al & r hs) {33.

    Pol ynomi al r es_pol ;34.

    35.

    res_pol . _sec = rhs. _sec;36.

    r es _pol . _ f i r = r hs. _ f i r ;37.

    res_pol . _con = l hs + rhs. _con;38.

    39.

    return r es_pol ;40.

    } / / end of Pol ynomi al operat or+( doubl e, Pol ynomi al &)41.

    42.

    Pol ynomi al & Pol ynomi al : :43.

    operat or =( const Pol ynomi a l rhs) {44.

    _sec = rhs. _sec;

    45.

    _ f i r += r hs. _ f i r ;46.

    _con += rhs. _con;47.

    48.

    return ( *t hi s) ;49.

    } / / end of Pol ynomi al & Pol ynomi al : : operat or+=( const Pol ynomi al )50.

    51.

    Pol ynomi al Pol ynomi al : :52.

    operat or - ( const Pol ynomi al rhs) {53.

    54.

    gramming Language Concepts Using C and C++/Parameterized Types... http://en.wikibooks.org/wiki/Programming_Language_Concepts_Using...

    f 33 20-11-2014 13:08

  • 8/10/2019 15 Programming Language Concepts Using C and C++_Parameterized Types - Wikibooks, open books for an ope

    23/33

    Pol ynomi al r es_pol ;

    55.

    res_pol . _sec =_s ec - rhs . _sec;56.

    r es _pol . _ f i r =_f i r - r hs. _ f i r ;57.

    res_pol . _con =_c on - rhs . _con;58.

    59.

    return r es_pol ;60.

    } / / end of Pol ynomi al Pol ynomi al : : operator - ( const Pol ynomi al )61.

    62.

    Pol ynomi al operat or - ( doubl e l hs, Pol ynomi al & r hs) {63.

    Pol ynomi al r es_pol ;

    64.

    65.

    res_pol . _sec = - r hs. _sec;66.

    r es _pol . _ f i r = - r hs . _ f i r ;67.

    res_pol . _con = l hs - r hs . _con;68.

    69.

    return r es_pol ;70.

    } / / end of Pol ynomi al operator - ( doubl e, Pol ynomi al &)71.

    72.

    Pol ynomi al Pol ynomi al : :73.

    operat or - =( const Pol ynomi al & r hs) {74.

    _sec - = rhs. _sec;75.

    _ f i r - = r hs. _ f i r ;76.

    _con - = rhs. _con;77.

    78.

    return ( *t hi s) ;79.

    } / / end of Pol ynomi al & Pol ynomi al : : operat or- =( const Pol ynomi al &)80.

    81.

    os t r ea oper at or

  • 8/10/2019 15 Programming Language Concepts Using C and C++_Parameterized Types - Wikibooks, open books for an ope

    24/33

    os

  • 8/10/2019 15 Programming Language Concepts Using C and C++_Parameterized Types - Wikibooks, open books for an ope

    25/33

    Pol ynomi al c4;18.

    cout

  • 8/10/2019 15 Programming Language Concepts Using C and C++_Parameterized Types - Wikibooks, open books for an ope

    26/33

    Pol ynomi al f( 3. 0, 4. 0) ;51.

    cout

  • 8/10/2019 15 Programming Language Concepts Using C and C++_Parameterized Types - Wikibooks, open books for an ope

    27/33

    gxx c Pol ynomi al . cxx # Usi ng DJ GPP- gxx

    gxx o Pol ynomi al _Test . exe Pol ynomi al _Test . cxx Pol ynomi al . o

    Pol ynomi al _Test Creat i ng c1 and i ni t i al i zi ng i t wi t h 1. . . c1: 1 Creat i ng c2 and i ni t i al i zi ng i t wi t h 2. . . c2: 2 Cr eati ng c3 and i ni t i al i zi ng i t wi t h an anonymous obj ect t hat has a val ue of 3. . .c3: 3 Creat i ng c4. . . I t i s aut omat i cal l y i ni t i al i zed wi t h 0. . . c4: 0

    Assi gni ng 4 t o c4. . . Creat i ng c5. . . I t i s aut omat i cal l y i ni t i al i zed wi t h 0. . . c5: 0 Assi gni ng c4 t o c5. . . c1: 1, c2: 2, c3: 3, c4: 4, c5: 4

    Test i ng compound assi gnment . . . Addi ng 1 t o c1. . . c1: 2 Subt ract i ng 1 f r om c3. . . c3: 2

    Test i ng t he equal i t y t est operat or . . . c3 == c1? Yes c2 == 2? Yes 4. 0 == c4? Yes c5 == c4? Yes

    Cr eat i ng f and i ni t i al i zi ng i t wi t h 4x + 3. . . f : 4x + 3 Cr eat i ng g and i ni t i al i zi ng i t wi t h 3x 2 + 2x + 1. . . g: 3x 2 + 2x + 1 Creat i ng h and i ni t i al i zi ng i t wi t h 2 + f - g + 4. . . h: - 3x 2 + 2x + 8 Usi ng f uncti on obj ect . . . f( g( 2) ) = 71, h( 3) = - 13

    Cr eati ng j ( on the heap) and k; j i s i ni t i al i zed wi t h 0 whi l e k wi t h 1 h: - 3x 2 + 2x + 8, j : 0, k: 1 Subt r act i ng 2x 2 + x f r om h, addi ng h t o k, and assi gni ng k to j . . . h: - 5x 2 + 1x + 8, j : - 5x 2 + 1x + 9, k: - 5x 2 + 1x + 9

    Filter.cxx

    #i ncl ude 1.

    #i ncl ude 2.

    #i ncl ude 3.

    usi ng namespace st d;4.

    5.

    t empl at e6.

    cl ass Fi l t er {7.

    publ i c:8.

    vi r t ual bool oper ator ( ) (T) = 0;9.

    }; / / end of (abs t ract ) c l ass Fi l ter10.

    11.

    cl ass EvennessFi l t er : publ i c Fi l t er

  • 8/10/2019 15 Programming Language Concepts Using C and C++_Parameterized Types - Wikibooks, open books for an ope

    28/33

    }; / / end of c l ass EvennessFi l ter15.

    16.

    cl ass NamesWi t hNLett ers Fi l t er : publ i c Fi l t er 26.

    vect or T f i l t ( vect or vec, Fi l terType f ) {27.

    vect or f i l t ered_vec;28.

    f or ( i nt i = 0; i

  • 8/10/2019 15 Programming Language Concepts Using C and C++_Parameterized Types - Wikibooks, open books for an ope

    29/33

    vector f i l t ered_names = f i l t ( st r _vec, NamesWi t hNLett ersFi l t er ( l en) ) ;48.

    49.

    f or ( i nt i = 0; i f i l tered_names. s i z e( ) ; i + )

    50.

    cout

  • 8/10/2019 15 Programming Language Concepts Using C and C++_Parameterized Types - Wikibooks, open books for an ope

    30/33

    (gr eat er), greater than or equal (gr eat er_equal ), less than (l ess), less than or equal(l ess_equal ).

    Example: Relational function objects.

    #i ncl ude #i ncl ude . . .

    What follows is the definition of a very simple function object class.

    cl ass l ess_t han_x {publ i c: l ess_t han_x( i nt x) { _x = x; } bool operator ( ) ( i nt r hs) { return rhs

  • 8/10/2019 15 Programming Language Concepts Using C and C++_Parameterized Types - Wikibooks, open books for an ope

    31/33

    Simulating Local Functions

    Local classes together with function objects can be used to simulate local functions. Using local classes provides protection

    from outside the current function whereas overriding the function call operator complements this by giving a sense of using

    functions.

    Local_Function.cxx

    #i ncl ude 1.

    usi ng namespace st d;2.

    qui cksort ( ) is a function template that we can use to instantiate functions that sort specific type of data, which isdetermined at the point of calling the function. On line 56 of the current program, for instance, a call using an array of

    i nt s is being made, which means the compiler or the compiler-linker pair will synthesize a version of the followingfunction that takes an array of i nt s.

    t empl at e 4.

    voi d qui cksort ( El mt _Type *ar r , i nt l , i nt r ) {5.

    c l ass Pi vot {6.

    publ i c:7.

    i nt oper at or ( ) ( El mt _Type *a r r , i nt l b, i nt ub) {8.

    El mt _Type v = ar r [ l b] ;9.

    i nt i = l b, j ub 1;10.

    11.

    do {12.

    Note comparison of the current array element with the first element of the array slice means we must make sure the

    less-than operator of the component type is implemented.

    do { j - - ; } whi l e (j ! = i && v < ar r [j ] ) ;13.

    i f ( i == j ) break;14.

    do { i + ; } whi l e ( i ! =j & ar r [ i ] v) ;15.

    i f ( i == j ) break;16.

    El mt _Type t mp = ar r [ i ] ;17.

    ar r [ i ] = ar r [j ] ;18.

    ar r [j ] = t mp;19.

    } whi l e ( i

  • 8/10/2019 15 Programming Language Concepts Using C and C++_Parameterized Types - Wikibooks, open books for an ope

    32/33

    21.

    i f (j ! = l b) {22.

    El mt _Type t mp = ar r [ l b] ;23.

    ar r [ l b] = ar r [j ] ;24.

    ar r [j ] = t mp;

    25.

    } / / end of i f ( j ! = l b)26.

    27.

    return j ;28.

    } / / end of i nt operator (El mt_Type*, i nt , i nt)29.

    }; / / end of ( l ocal ) c l ass Pi vot30.

    31.

    Pi vot pi vot ;32.

    i nt i pi vot ( ar r , l , r ) ;33.

    34.

    i f ( l

  • 8/10/2019 15 Programming Language Concepts Using C and C++_Parameterized Types - Wikibooks, open books for an ope

    33/33

    r andom_shuff l e( array[ 0] , ar r ay[ no_of _i t ems] ) ;49.

    50.

    cout