• Advertisement

Archived

This topic is now archived and is closed to further replies.

What is wrong with my template function?

This topic is 5128 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Main.h
#ifndef _Main_h
#define _Main_h



template<class dataType>
class CArray
{

     dataType * _array;
     int _size;
     
     public:
     
        CArray(void): _size(20)
        {
        
           _array = new dataType[_size];
        }
        
        CArray(int paramSize): _size(paramSize)
        {
        
           _array = new dataType[_size];
        }
        
        ~CArray(void)
        {
        
           if( _array != NULL )
           {

              delete [] _array;
           }
           
           _array = NULL;
        }
        
        operator dataType*(void)
        {
        
           return _array;
        }
        
        dataType & operator[](int element)
        {
        
           return _array[element];
        }
        
        void resize(int newSize)
        {

           if( _array != NULL )
           {

              delete [] _array;
           }
           
           _array = NULL;
           _size = newSize;

           _array = new dataType[newSize];
        }
        
        void insert(int element, dataType value)
        {
        
           for( int index = _size - 1; index > element; index-- )
           {
           
              _array[index] = _array[index - 1];
           }
           
           _array[element] = value;
        }

        void clear(dataType zero)
        {
        
           for( int index = 0; index < _size; index++ )
           {
           
              _array[index] = zero;
           }
           
        }

        int GetSize(void) const
        {
        
           return _size;
        }
        
};


#endif
Main.cpp
#include <iostream>
#include <cstdlib>
#include <time.h>

#include "Main.h"

   using std::cout;
   using std::cin;
   using std::endl;
   
   template<typename dataType, const int MAX, dataType value>
   void Process(dataType*&);
   
   template<typename dataType, const int MAX>
   void Process2(dataType*);
   

   
int main(void)
{

     srand( (int)time(NULL) );
     CArray<int> array(9);

     Process<int, array.GetSize(), int(rand() % 10)>(array);
     
     cin.get();
     return EXIT_SUCCESS;
}


template<typename dataType, int MAX, dataType value>
void Process( dataType *& pArray )
{

     for( int index = 0; index < MAX; index++ )
     {
     
        pArray[index] = value;
     }

}


template<typename dataType, const int MAX>
void Process2( dataType * pArray )
{

     for( int index = 0; index < MAX; index++ )
     {
     
        cout << pArray[index] << endl;
     }
     
}
-------- "Do you believe in Ghost?"

Share this post


Link to post
Share on other sites
Advertisement
Is this a compile time error or a runtime error? I''m not going to look through your code unless I have at least some idea what your problem is.

Share this post


Link to post
Share on other sites
i could be wrong, (which i probably am, buuut)...isn' tthe syntax for declaring a template thus:


template <class type>
void F(type t)
{
t = t;
}


notice the "class" keyword...
am i missing something? otherwise you haven't declared "typename" anywhere...

------------------------------------------
Post Reply

[edited by - MrBeaner on February 7, 2004 12:52:27 AM]

Share this post


Link to post
Share on other sites
Both typename and class are legit, unless your template parameter is itself a template.


“Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.”
— Brian W. Kernighan (C programming language co-inventor)

Share this post


Link to post
Share on other sites
All template parameters must be compile-time constants... that means you cannot do:

Process<int, array.GetSize(), int(rand() % 10)>(array);


since "int(rand() % 10" is not a compile-time constant.

Share this post


Link to post
Share on other sites
Its a compile error on the line Daniel just pointed out.

What do you mean by compile-constant?

--------
"Do you believe in Ghost?"

Share this post


Link to post
Share on other sites
quote:
Original post by Fruny
Both typename and class are legit, unless your template parameter is itself a template.


“Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.”
— Brian W. Kernighan (C programming language co-inventor)



What is the difference between the two?

Share this post


Link to post
Share on other sites
MrBeaner: There is no difference. [/matrix reference] Seriously. class and typename are interpreted the same way in template parameter lists.

Share this post


Link to post
Share on other sites
quote:
Original post by MrBeaner
What is the difference between the two?


Within a template declaration, they are completely interchangeable.
Only when you have something of the form template <template<typename T> class U> ... is the 'outer' class mandatory (because U really is a class).

The typename keyword has other usages, all related to the need to disambiguates between members which are variables/functions... and members which are types:

template <class Container>
typename T::value_type
first(Container c)
{
return *(c.begin());
}


Without the typename keyword, your compiler would interpret T::value_type as a static member. typename precises that it really is a type. Since T is not yet known when you write the template, you have to specify which one is right.

[edited by - Fruny on February 8, 2004 1:51:09 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by Leiarchy9
Its a compile error on the line Daniel just pointed out.

What do you mean by compile-constant?

--------
"Do you believe in Ghost?"




A compile constant is a constant which value is known at compile-time...
For example:

int b;
ExampleClass<2+4*3> a; //You can do this, since 2+4*3 is a constant that is known at compile-time

ExampleClass<3*b> c; //This cause an error, since you don`t know at compile time what will be the value of "b" by the time this line is executed in runtime

Share this post


Link to post
Share on other sites
I made some changes but I''m getting a different error about my conversion operator.

Main.cpp

#include <iostream>
#include <cstdlib>
#include <time.h>

#include "Main.h"

using std::cout;
using std::cin;
using std::endl;

template<typename dataType, const int MAX>
void Process(dataType*&, dataType);

template<typename dataType, const int MAX>
void Process2(dataType*);



int main(void)
{

srand( (int)time(NULL) );
CArray<int> array(9);

Process<int, 9>( array, int(rand() % 10) );
Process2<int, 9>( array );

cin.get();
return EXIT_SUCCESS;
}


template<typename dataType, int MAX>
void Process( dataType *& pArray, dataType paramValue )
{

for( int index = 0; index < MAX; index++ )
{

pArray[index] = paramValue;
}

}


template<typename dataType, const int MAX>
void Process2( dataType * pArray )
{

for( int index = 0; index < MAX; index++ )
{

cout << pArray[index] << endl;
}

}


Main.h

#ifndef _Main_h
#define _Main_h



template<class dataType>
class CArray
{

dataType * _array;
int _size;

public:

CArray(void): _size(20)
{

_array = new dataType[_size];
}

CArray(int paramSize): _size(paramSize)
{

_array = new dataType[_size];
}

~CArray(void)
{

if( _array != NULL )
{

delete [] _array;
}

_array = NULL;
}

operator dataType*(void)
{

return _array;
}

operator dataType*&(void)
{

return _array;
}

dataType & operator[](int element)
{

return _array[element];
}

void resize(int newSize)
{

if( _array != NULL )
{

delete [] _array;
}

_array = NULL;
_size = newSize;

_array = new dataType[newSize];
}

void insert(int element, dataType value)
{

for( int index = _size - 1; index > element; index-- )
{

_array[index] = _array[index - 1];
}

_array[element] = value;
}

void clear(dataType zero)
{

for( int index = 0; index < _size; index++ )
{

_array[index] = zero;
}

}

int GetSize(void)
{

return _size;
}

};


#endif


--------
"Do you believe in Ghost?"

Share this post


Link to post
Share on other sites
The compile error is:

Main.cpp:26: conversion from `CArray'' to `int*'' is ambiguous
Main.h:40: candidates are: CArray::operator dataType*() [with
dataType = int]

--------
"Do you believe in Ghost?"

Share this post


Link to post
Share on other sites
quote:
Original post by Fruny
quote:
Original post by MrBeaner
What is the difference between the two?


Within a template declaration, they are completely interchangeable.
Only when you have something of the form template <template<typename T> class U> ... is the ''outer'' class mandatory (because U really is a class).

The typename keyword has other usages, all related to the need to disambiguates between members which are variables/functions... and members which are types:

template <class Container>
typename T::value_type
first(Container c)
{
return *(c.begin());
}

thanks for the info... i thin i need to buy a book on templates and read up on them... i have a basic understanding, but nothing super powerful.

It''s to bad i''m broke right now


Without the typename keyword, your compiler would interpret T::value_type as a static member. typename precises that it really is a type. Since T is not yet known when you write the template, you have to specify which one is right.

[edited by - Fruny on February 8, 2004 1:51:09 AM]


Share this post


Link to post
Share on other sites
quote:
Original post by Leiarchy9
I made some changes but I'm getting a different error about my conversion operator.

 
int main()
{
...
Process<int, 9>( array, int(rand() % 10) );
Process2<int, 9>( array );
...
}




You're using int as first template argument here so Process & Process2 expects an int*. But you're passing in a CArray<int> as parameter so you're going to get a conversion error. Maybe you're looking for this instead:


Process<CArray<int>, 9> (array, rand()%10);
Process2<CArray<int>, 9> (array);


Also look in the STL to see if there's a container that'll do what you want. It'll make things easier.





--{You fight like a dairy farmer!}

[edited by - Greatwolf on February 9, 2004 3:23:40 AM]

Share this post


Link to post
Share on other sites
just wanted to note that I can''t believe you posted code twice without telling us what the error message was either time.

Share this post


Link to post
Share on other sites
GreatWolf your code doesn''t work.

I''m getting an error about converting ''array'' or something.

--------
"Do you believe in Ghost?"

Share this post


Link to post
Share on other sites

void Process(dataType &pArray);
void Process2(dataType pArray);






--{You fight like a dairy farmer!}

Share this post


Link to post
Share on other sites
*& is the source of all your troubles.

Get rid of it throughout your source. You only need *& types when changing the value of the pointer itself, not the data it points to.

Ambiguity between *& and * operators is probably also causing potentail errors. Ambiguity between, say int and int* is another well known issue for the value 0, but thats another story.

So,

1. Get rid of operator*&
2. Make Process take a Type* instead of Type*&

HTH


blah blah blah.

Share this post


Link to post
Share on other sites
And also, I forgot to mention that I got your program to work doing only those two things.


blah blah blah.

Share this post


Link to post
Share on other sites
I now got my code working but there was a reason why I had Process() take a dataType*& was because I wanted to change the pointer''s value like so:


template<typename dataType, int MAX>
void Process( dataType * pArray, dataType paramValue )
{

for( int index = 0; index < MAX; index++ )
{

pArray[index] = paramValue;
}

}


Now you said that I only need to use the reference sign when I''m changing the pointer itself not the data it points to. I''m assuming that what you mean by ''the pointer itself'' is ''pArray''? So that would mean that ''pArray(index]'' would be the data it points to right?

--------
"Do you believe in Ghost?"

Share this post


Link to post
Share on other sites
Right.



int array[5];

array is a constant pointer, its value being the start of the array, and array[0] is the first element, the element array points to.

You would need a *& if you wanted to do this

void allocate_mem(int*& array)
{
array = new int[5];
}

, because

void allocate_mem(int* array)
{
array = new int[5];
}

wouldn''t do the job, as array wouldn''t be changed outside the function, since the pointer is passed by value.






blah blah blah.

Share this post


Link to post
Share on other sites

  • Advertisement