passing arguments with template class

Oct 14, 2009 at 2:11am
How do you pass an argument with a template class?
I have a templated class in a .h and then a main.cpp
and in my main.cpp I am getting an error that says the parameter of my main.cpp function is not declared.

this is the code I have for the .h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
template < class T >
   class sequence
   {...}
#endif

#include "sequenceTest.cpp"
namespace cs3358Fall2009Assign04
{
   template < class T >
   sequence< T >::sequence()
   {
      used = 0;
      current_index = 0;
   }


and this is main.cpp where the problem is in the function header.
 
void show_list(sequence<T>);
Oct 14, 2009 at 2:42am
1
2
template <typename T>
void show_list(sequence<T>);


EDIT: Note that in the context of template parameter declaration, class and typename are synonymous. I just like typename better.
Last edited on Oct 14, 2009 at 2:44am
Oct 14, 2009 at 3:23am
Amazing...Thanks so much...that eliminated almost all of my errors.

I just have one other question

in my main.cpp in my show_list function
1
2
3
4
5
void show_list(sequence < T >)
{
   for ( src.start(); src.is_item(); src.advance() )
      cout << src.current() << "  ";
}


it says src is not declared
so if I am using it for either int or char how do I delcare it? Would I use T?

like T.start or sequence<T> src.start ?
Last edited on Oct 14, 2009 at 3:27am
Oct 14, 2009 at 4:29am
Uh... You have to name the parameter in the function definition in order to use it. How else do you expect the compiler to know what you're talking about?
Oct 14, 2009 at 4:44am
I am not sure if I am understanding, but something like this?

void show_list (sequence <T>, T src)
{...}
Oct 14, 2009 at 4:47am
No. This:
template <typename T>
void show_list(sequence<T> src)
Oct 14, 2009 at 4:58am
ok this is what I did
1
2
3
4
5
6
template <class T>
void show_list(sequence < T > src)
{
   for ( src.start(); src.is_item(); src.advance() )
      cout << src.current() << "  ";
}



I would need to do that to the function header as well right. Like this?

1
2
3
4
template <class T>
void show_list(sequence<T> src);
// Pre: (none)
// Post: The items of src are printed to cout (one per line). 
Oct 14, 2009 at 5:03am
That works except I have to comment out the #include "sequenceTest.cpp"
in the .h and I get errors that say expected init-declarator before size and i am not sure why.
this is my function definition in the .h under my template class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
namespace cs3358Fall2009Assign04
{
   template < class T >
   sequence< T >::sequence()
   {
      used = 0;
      current_index = 0;
   }
   template < class T >
   void sequence< T >::start() { current_index = 0; }
   template < class T >
   void sequence< T >::advance()
   {
      assert( is_item() );
      ++current_index;
   }
   template < class T >
   void sequence< T >::insert(const value_type& entry)
   {
      assert( size() < CAPACITY );

      size_type i;

      if ( ! is_item() )
         current_index = 0;
      for (i = used; i > current_index; --i)
         data[i] = data[i - 1];
      data[current_index] = entry;
      ++used;
   }
   template < class T >
   void sequence< T >::attach(const value_type& entry)
   {
      assert( size() < CAPACITY );

      size_type i;

      if ( ! is_item() )
         current_index = used - 1;
      for (i = used; i > current_index + 1; --i)
         data[i] = data[i - 1];
      data[current_index + 1] = entry;
      ++current_index;
      ++used;
   }
   template < class T >
   void sequence <T>::remove_current()
   {
      assert( is_item() );

      size_type i;

      for (i = current_index + 1; i < used; ++i)
         data[i - 1] = data[i];
      --used;
   }
   template < class T >
   int sequence< T >::size_type size() const
   { return used;
   }
   template < class T >
   bool sequence< T >::is_item() const { return (current_index < used); }
   template < class T >
   int sequence< T >::value_type current() const
   {
      assert( is_item() );

      return data[current_index];
   }
}


I really appreciate the help I have been working on this all day.
Oct 14, 2009 at 5:06am
This one:
1
2
template < class T >
int sequence< T >::size_type size() const

What is this supposed to be called? size_type or size?

EDIT: Oh, please don't double-post. I missed your other question because I just looked at the last post. There's an "edit" button for a reason.

You can name the parameter in the function declaration, but it's not necessary.
Last edited on Oct 14, 2009 at 5:07am
Oct 14, 2009 at 5:08am
this is the class
I think it is size_type size() const;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
template < class T >
   class sequence
   {
   public:
      // TYPEDEFS and MEMBER CONSTANTS
      typedef double value_type;
      typedef size_t size_type;
      static const size_type CAPACITY = 10;
      // CONSTRUCTOR
      sequence();
      // MODIFICATION MEMBER FUNCTIONS
      void start();
      void advance();
      void insert(const value_type& entry);
      void attach(const value_type& entry);
     void remove_current();
      // CONSTANT MEMBER FUNCTIONS
      size_type size() const;
      bool is_item() const;
      value_type current() const;

   private:
      value_type data[CAPACITY];
      size_type used;
      size_type current_index;
   };


EDIT: Sorry about the double post it was unintentional.
Last edited on Oct 14, 2009 at 5:17am
Oct 14, 2009 at 5:17am
Okay, so it's supposed to return sequence< T >::size_type. So why did you put int there?
template < class T >
int sequence< T >::size_type size() const

You did the same for current().
Oct 14, 2009 at 5:20am
I did that because it says I need some type of constructor, destructor, or type conversion before "size" so I thought it had to be something and I figured size was a number?
Last edited on Oct 14, 2009 at 5:21am
Oct 14, 2009 at 5:42am
No. Remove them. A function must always have exactly one return type in front of its name.

As for the error, is sequence in the cs3358Fall2009Assign04 namespace? The fact that you didn't get any other errors would seem to suggest that it is, but if that's the case, then I have no idea what the problem could be.
Why don't you try moving your function definitions inside the class?
Oct 14, 2009 at 12:37pm
why would I get a warning here that says converting to char from double? I initialized s2 as sequence < char > s2 ;

1
2
3
4
5
6
7
8
9
10
11
12
else
            {
               if ( s2.is_item() )
               {
                  charHold = s2.current();
                  s2.remove_current();
                  cout << charHold << " removed from s2." << endl;
               }
               else
                  cout << "s2 has no current item." << endl;
            }
            break;
Last edited on Oct 14, 2009 at 1:42pm
Oct 14, 2009 at 2:33pm
typedef double value_type;
Oct 14, 2009 at 2:43pm
ARGH! Stupid cancel button! Let me see if I can retype it right:

As for the "constructor, destructor, or type conversion" stuff, it is because you need to explictly instruct the compiler that you are using a type -- as it is possible that it isn't.
1
2
3
4
5
6
   template < class T >
   typename sequence< T >::size_type
   size() const
   {
      return used;
   }

As for the "char to double" problem, you haven't given us enough information to solve that one... is charHold a double?
Oct 14, 2009 at 2:49pm
But... size_type is clearly a typedef of size_t.
Oct 14, 2009 at 3:01pm
Yes, to us humans. Computers are stupid, and they can't cut through the potential vagary.
See http://www.parashift.com/c++-faq-lite/templates.html#faq-35.18 for the amazing details. :-)
Oct 14, 2009 at 4:19pm
No, charHold is a char

1
2
3
4
5
6
7
8
int main(int argc, char *argv[])
{
   sequence < double > s1;    // A sequence of double for testing
   sequence < char > s2 ;       // A sequence of char for testing
   int objectNum;    // A number to indicate selection of s1 or s2
   double numHold;   // Holder for a real number
   char charHold;    // Holder for a character
   char choice;      // A command character entered by the user 

...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
case 'R':
            objectNum = get_object_num();
            if (objectNum == 1)
            {
               if ( s1.is_item() )
               {
                  numHold = s1.current();
                  s1.remove_current();
                  cout << numHold << " removed from s1." << endl;
               }
               else
                  cout << "s1 has no current item." << endl;
            }
            else
            {
               if ( s2.is_item() )
               {
                  charHold = s2.current();
                  s2.remove_current();
                  cout << charHold << " removed from s2." << endl;
               }
               else
                  cout << "s2 has no current item." << endl;
            }
            break;


EDIT:

s2.current returns the ascii value of the char entered. I enter f and get 102. so somehow data [] is not returning the letter but the value of the letter.
Last edited on Oct 14, 2009 at 4:45pm
Topic archived. No new replies allowed.