generic functions: <typename T> or <class T>

This is a discussion on generic functions: <typename T> or <class T> within the C++ Programming forums, part of the General Programming Boards category; I am trying to create some general functions that operate on containers and was wondering when creating it should I ...

  1. #1
    Ethernal Noob
    Join Date
    Nov 2001
    Posts
    1,901

    generic functions: <typename T> or <class T>

    I am trying to create some general functions that operate on containers and was wondering when creating it should I use

    template <class T>
    or


    template <typename T>
    I figure i should use typname T if I am creating generic functions for primitive continers and class for class types. Am I wrong. I found online conflicting ways to do it so I can't assume one or the other.

  2. #2
    Registered User
    Join Date
    Jan 2005
    Posts
    7,317
    It doesn't matter. Some people use the convention of class for more complex class types, and typename for a function that can be used with built-in types or class types like you suggested. It really doesn't matter, though. Pick a style and stick with it.

  3. #3
    Ethernal Noob
    Join Date
    Nov 2001
    Posts
    1,901
    cool, now I wonder why it's not recognizing the function;

    I have a vector I'm making using a function that returns a reference to an array but when I try to use it I get a

    [code]main.cpp:21: error: no matching function for call to `fillArray(std::istream&)'[code]

    here is my header file
    Code:
    #ifndef ALGOS_H
    #define ALGOS_H
    
    #include <iostream>
    #include <vector>
    
    template<class T>
    std::vector<T> fillArray(std::istream&);
    
    int find_majority(std::vector<int>&);
    
    #endif
    and here's my source file
    Code:
    #include <iostream>
    #include <cstdlib>
    #include <iterator>
    #include "algos.h"
    
    using std::vector;
    using std::istream;
    
    using std::istream_iterator;
    
    template<class T>
    vector<T> fillArray(istream& in)
    {
    	vector<T> aVec;
    	istream_iterator<T> inIter(in), eof;
    	copy(inIter, eof, back_inserter(aVec));
    	return aVec;
    }
    
    int find_majority(std::vector<int>& arr)
    {
    	typedef vector<int>::size_type vSize;
    	vector<int> possibles;
    	if(arr.begin() == arr.end())
    		return -1;
    	else if(arr.size() == 1)
    		return arr[0];
    	else
    	{
    		vSize arrSize = arr.size();
    		if(arrSize % 2  == 1)
    		{
    			possibles.push_back(arr[arrSize - 1]);
    			--arrSize;
    		}
    		for(vSize i = 0; i < arrSize; ++i)
    		{
    			vSize j = i + 1;
    			if(arr[i] == arr[j])
    				possibles.push_back(arr[i]);
    			++i;
    		}
    	}
    	return find_majority(possibles);
    }
    and here is the test file
    Code:
    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include "algos.h"
    
    using std::vector;
    
    using std::cout;
    using std::cin;
    
    using namespace std;
    
    int main(int argc, char *argv[])
    {
    	vector<int> numArr(fillArray(cin));
    	
    	int maj = find_majority(numArr);
    	
    	if(maj < 0)
    		cout << "\n\nThis array has no majority element";
    	else
    		cout << "\n\nThe majority element is: " << maj;
    
    	return 0;
    }

  4. #4
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,893
    Two problems.

    First, because the template parameter doesn't appear in the arguments list, the compiler cannot deduce it. You need to explicitly specify it:
    vector<int> numArr(fillArray<int>(cin));

    Second, you must put the implementation of templates in header files. This is because of the way templates work. If you don't, you'll get unresolved externals in the link phase.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  5. #5
    Ethernal Noob
    Join Date
    Nov 2001
    Posts
    1,901
    Also is it okay to return a reference.

  6. #6
    Registered User
    Join Date
    Jan 2005
    Posts
    7,317
    For the fillArray? Not in this case, since the reference would be to the local vector which would be destroyed when the function ends. To avoid the copy add an extra reference parameter and pass the vector in the way you do for find_majority.

  7. #7
    Ethernal Noob
    Join Date
    Nov 2001
    Posts
    1,901
    OK I see, that's what I started to do but the implementation was seperate and it wouldn't have worked anyway. Thanks for your help.

    this is my new method in the header file

    Code:
    template<class T>
    std::vector<T> fillArray(std::istream& in);
    {
    	std::istream_iterator<T> inIter(in), eof;
    	std::vector<T> aVec(inIter, eof);
    	std::copy(inIter, eof, back_inserter(aVec));
    	return aVec;
    }
    I love iterators. It's hard to go back to java having not learned iterators for those yet. I can probably learn it quick but still. Though I miss for( each : container)
    Last edited by indigo0086; 09-29-2006 at 11:25 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Generic List Functions
    By mike_g in forum C Programming
    Replies: 4
    Last Post: 08-09-2007, 02:29 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21