Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

how can i use the template in Separation Model??

Posted on 2003-10-29
4
287 Views
Last Modified: 2010-04-02
//Array.h
#include <iostream>
using std::ostream;
using std::cout;
using std::endl;

template <class elemType> class Array;
template <class elemType> ostream&
          operator<<( ostream &, Array<elemType> & );

template <class elemType>
class Array {
public:
    // explicit Array( int sz = DefaultArraySize )
    Array( int sz = DefaultArraySize )
         { init( 0, sz ); }

    Array( const elemType *ar, int sz )
         { init( ar, sz ); }

    Array( const Array &iA )
         { init( iA._ia, iA._size ); }

    virtual ~Array() { delete[] _ia; }

    Array& operator=( const Array & );
    int size() const { return _size; }

    virtual elemType& operator[]( int ix ) { return _ia[ix]; }
    virtual elemType  operator[]( int ix ) const { return _ia[ix]; }

    elemType at( int ix ) const { return _ia[ ix ]; }

    virtual ostream &print( ostream& os = cout ) const;
    virtual void grow();

protected:
    void init( const elemType*, int );

    // static const int DefaultArraySize = 12;
    static const int DefaultArraySize;
    int       _size;
    elemType *_ia;
};

template <class Type>
        Type min( Type a, Type b ) {
                return a < b ? a : b;
}

template <class elemType>
        void swap( Array<elemType> &array, int i, int j )
{
        elemType tmp = array[ i ];
        array[ i ] = array[ j ];
        array[ j ] = tmp;
}

//Array.cpp
#include "array.h"
#include <cassert>

template <class elemType>
  const int Array<elemType>::DefaultArraySize = 12;

template <class elemType>
    void Array<elemType>::init( const elemType *array, int sz )
{
    if ( ! array ) { _size = 0; _ia = 0; }
    if ( sz < 1 ) sz = 1;

    _size = sz;
    _ia = new elemType[ _size ];

    if ( ! array ) return;

    for ( int ix = 0; ix < _size; ++ix )
       _ia[ ix ] = array[ ix ];
}

template <class elemType> Array<elemType>&
    Array<elemType>::operator=( const Array<elemType> &iA )
{
    if ( this == &iA )
         return *this;

    delete[] _ia;
    init( iA._ia, iA._size );
    return *this;
}

template <class elemType> ostream&
    operator<<( ostream &os, Array<elemType> &ar )
{
    return ar.print( os );
}

template <class elemType>
    ostream& Array<elemType>::print( ostream &os ) const
{
    const int lineLength = 12;
    os << "( " << _size << " )< ";

    for ( int ix = 0; ix < _size; ++ix )
    {
          if ( ix % lineLength == 0 && ix )
               os << "\n\t";

          os << _ia[ ix ];
          // don't generate comma for last item on line
          // nor for the last element of the array
          if ( ix % lineLength != lineLength-1 && ix != _size-1 )
               os << ", ";
    }

    os << " >\n";
    return os;
}

template <class elemType>
    void Array<elemType>::grow()
{
    elemType *oldia = _ia;
    int oldSize = _size;

    _size = oldSize + oldSize/2 + 1;
    _ia   = new elemType[_size];

    int ix;
    for ( ix = 0; ix < oldSize; ++ix)
          _ia[ix] = oldia[ix];

    for ( ; ix < _size; ++ix )
       _ia[ix] = elemType();

    delete[] oldia;
}

//Algo.cpp
template <class elemType>
        void sort( Array<elemType> &array, int low, int high ) {
        if ( low < high ) {
                int lo = low;
                int hi = high + 1;
                elemType elem = array[lo];

                for (;;) {
                        while ( min( array[++lo], elem ) != elem && lo < high ) ;
                        while ( min( array[--hi], elem ) == elem && hi > low ) ;

                        if (lo < hi)
                                swap( array, lo, hi );
                        else break;
                }

                swap( array, low, hi );
                sort( array, low, hi-1 );
                sort( array, hi+1, high );
        }
}

template <class elemType>
        void display( Array<elemType> &array )
{ // display format: < 0 1 2 3 4 5 >

        cout << "< ";
        for ( int ix = 0; ix < array.size(); ++ix )
                cout << array[ix] << " ";
        cout << ">\n";
}

//the main program
#include <string>
using std::string;

#include "Array.h"
#include "Algo.cpp"

double da[10] = {
        26.7, 5.7, 37.7, 1.7, 61.7, 11.7, 59.7,
        15.7, 48.7, 19.7 };

int ia[16] = {
        503, 87, 512, 61, 908, 170, 897, 275, 653,
        426, 154, 509, 612, 677, 765, 703 };

string sa[11] = {
        "a", "heavy", "snow", "was", "falling", "when",
        "they", "left", "the", "police", "station" };

int main() {

        // call the constructor to initialize arrd
        Array<double> arrd( da, sizeof(da)/sizeof(da[0]) );

        // call the constructor to initialize arri
        Array<int> arri( ia, sizeof(ia)/sizeof(ia[0]) );

        // call the constructor to initialize arrs
        Array<string> arrs( sa, sizeof(sa)/sizeof(sa[0]) );

        cout << "sort array of doubles (size == "
             << arrd.size() << ")" << endl;
        sort(arrd, 0, arrd.size()-1 );
        display(arrd);

        cout << "sort array of ints (size == "
             << arri.size() << ")" << endl;
        sort(arri, 0, arri.size()-1 );
        display(arri);

        cout << "sort array of strings (size == "
             << arrs.size() << ")" << endl;
        sort(arrs, 0, arrs.size()-1 );
         display(arrs);

        return 0;
}
but so many messages:
Compiling...
main11.cpp
Linking...
main11.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Array<double>::grow(void)" (?grow@?$Array@N@@UAEXXZ)
main11.obj : error LNK2001: unresolved external symbol "public: virtual class std::basic_ostream<char,struct std::char_traits<char> > & __thiscall Array<double>::print(class std::basic_ostream<char,struct std::char_traits<char> > &)const " (?print@?
$Array@N@@UBEAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV23@@Z)
main11.obj : error LNK2001: unresolved external symbol "protected: void __thiscall Array<double>::init(double const *,int)" (?init@?$Array@N@@IAEXPBNH@Z)
main11.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Array<int>::grow(void)" (?grow@?$Array@H@@UAEXXZ)
main11.obj : error LNK2001: unresolved external symbol "public: virtual class std::basic_ostream<char,struct std::char_traits<char> > & __thiscall Array<int>::print(class std::basic_ostream<char,struct std::char_traits<char> > &)const " (?print@?$Ar
ray@H@@UBEAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV23@@Z)
main11.obj : error LNK2001: unresolved external symbol "protected: void __thiscall Array<int>::init(int const *,int)" (?init@?$Array@H@@IAEXPBHH@Z)
main11.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Array<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >::grow(void)" (?grow@?$Array@V?$basic_string@DU?$char_traits@D@std
@@V?$allocator@D@2@@std@@@@UAEXXZ)
main11.obj : error LNK2001: unresolved external symbol "public: virtual class std::basic_ostream<char,struct std::char_traits<char> > & __thiscall Array<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >::print
(class std::basic_ostream<char,struct std::char_traits<char> > &)const " (?print@?$Array@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@@UBEAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV23@@Z)
main11.obj : error LNK2001: unresolved external symbol "protected: void __thiscall Array<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >::init(class std::basic_string<char,struct std::char_traits<char>,class
 std::allocator<char> > const *,int)" (?init@?$Array@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@@IAEXPBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@H@Z)
Debug/main11.exe : fatal error LNK1120: 9 unresolved externals
Error executing link.exe.

main11.exe - 10 error(s), 0 warning(s)

how can i use the template in Separation Model??

thanks!
0
Comment
Question by:weileng_ghost
  • 3
4 Comments
 
LVL 30

Expert Comment

by:Axter
ID: 9647022
You can not put the template code inside a *.cpp file.

You need to put it in the header.
0
 
LVL 30

Accepted Solution

by:
Axter earned 85 total points
ID: 9647068
In order to put the code inside the *.cpp file, your compiler has to support export keyword.

There's only one compiler that support this, and VC++ is not it.

The only other way to get around this, is to include forward template class declarations inside the *.cpp file that contains the template implementation.
template foo<int>; //Forward declaration of int type for foo


Example for your code:


//Algo.cpp

template Array<int>;
template Array<double>;
template Array<string>;
template Array<int>;

template <class elemType>
       void sort( Array<elemType> &array, int low, int high ) {
       if ( low < high ) {
               int lo = low;
               int hi = high + 1;
               elemType elem = array[lo];

               for (;;) {
                       while ( min( array[++lo], elem ) != elem && lo < high ) ;
                       while ( min( array[--hi], elem ) == elem && hi > low ) ;

                       if (lo < hi)
                               swap( array, lo, hi );
                       else break;
               }

               swap( array, low, hi );
               sort( array, low, hi-1 );
               sort( array, hi+1, high );
       }
}

template <class elemType>
       void display( Array<elemType> &array )
{ // display format: < 0 1 2 3 4 5 >

       cout << "< ";
       for ( int ix = 0; ix < array.size(); ++ix )
               cout << array[ix] << " ";
       cout << ">\n";
}

0
 

Author Comment

by:weileng_ghost
ID: 9647824
ok,it works well.thanks a lot!!!
by the way,which compiler supports the separation Model?
0
 
LVL 30

Expert Comment

by:Axter
ID: 9649264
I forgot which one.  It was in the C++ Jornal magazine a few months ago.

I think it's either edg or Comeau
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
returning a dereferenced pts in C++ 10 158
Exception thrown at 0x00007FFD5BC81F28 7 49
Dialogbox API leak? 18 98
Create a path if not exists 7 89
Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

861 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question