Help with generic vectors

Hi,

Does anybody know how I would create a vector with a generic type? Basically, I need an array (vector) of size 3 that will receive input from the user and return the max value. It has to be a generic type because it must work with int, double and string values. Here is what I tried but I don't think it's right:

1
2
3
const int ARRAY_SIZE = 3; //defining the size of the array
template<typename T> //defining generic type
vector<T> myArray(ARRAY_SIZE); //defining array size 
Last edited on
You mean like defining a vector inside a template class? Just use the outer template parameter T as if it were a type.

e.g.
1
2
3
4
5
template<typename T>
class ArrayClass {
     const int ARRAY_SIZE = 3;
     vector<T> myArray(ARRAY_SIZE);
};

Then ArrayClass<int> instances will have internal vectors of ints.
I'm not good with classes... But you showed me how to create a vector array with a generic type. Now I just need to create a function to return the max value of that array. Thanks!
If the function is a template function, it should work similarly. But you can't just pull T from nowhere; there has to be an outer template declaration for it.
Generics do not exist in C++. C++ has "templates". Templates (like vector) are not classes themselves, but are more of like the blueprint for classes to be created.

That is, the compiler (at compile time) generates 2 entirely different classes for vector<int> and vector<double>. They are distinctly different types and cannot be interchanged. You also cannot pick which one you want at run-time because it's a compile-time thing.


There are classes that can be used to represent multiple types (such as the any class in boost). With that you could do:
std::vector<boost::any>, but those kinds of classes are typically awkward to use in my experience.


Personally... I think you just need to rethink this design. Why would you want the user to be able to specify a compile-time type?
Basically, I need a function with the array of generic type and its size as parameters. This function will return the max size of the array. I need to make that work with int, double and string, that's why I need a template. So, here is what I have so far:

1
2
3
4
5
6
7
8
9
10
11
template<typename T>

T maxValue(const int ARRAY_SIZE = 3, vector<T> myArray(ARRAY_SIZE)) //defining what the function does
{
	for (int i=0; i<ARRAY_SIZE; i++)

	if (value < myArray[i])
	{
		value=i+1;
	}
	return value;
Last edited on
In this case, it looks OK except for the fact that you are doing two things that are illegal:
* You specify a default value for the first parameter but not for the following
* You are explicitly trying to indicate what constructor you want for one of the parameters

You may be able to get away with something like vector<T> myArray = vector<T>(ARRAY_SIZE) as the second parameter but I don't recall whether previous parameters are actually in scope then.
Well, since I understand the concept of vectors but still having a hard time to get it to work with templates, I just used arrays. Here is my final result, in 3 files:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//MaximumInArray.cpp

/**************************************************************
In this file we define what the template function max will do *
which is, return the max value of the array.                  *
***************************************************************/

#include "MaximumInArray.h" //Requiring header file MaximumInArray.h

//Template class with a function that will return the max value of an array of 5 elements
template<class T> T max(const T* data, const int size = 5) 
{
	T result = data[0];
    for(int i = 1 ; i < size ; i++)
      if(result < data[i])
        result = data[i];
    return result;
  }


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
//MaximumInArray.h

/**************************************************************
Program 12.1 - Maximum In Array                               *
Name: Anderson Oliveira Fernandes                             *
Date: March 7, 2013                                           *
***************************************************************/

/**************************************************************
                    Program Description                       *
                                                              *
Design a generic function that returns a maximum element      *
from an array. The function should have two parameters. One   *
is the array of a generic type, and the other is the size     *
of the array. Test the function with the array of int,        *
double and string values.                                     *
*************************************************************/

/**************************************************************
In this file, we load the libraries necessary for the program *
to run. It also declares the template function max, that will *
return the max value each of the arrays.                      *
***************************************************************/

#ifndef MAXIMUMINARRAY_H
#define MAXIMUMINARRAY_H

#include <string> //Needed for string manipulation
#include <iostream>

// Declaring the function that will return the max value in the array
template<class T> T max(const T* data, const int size);


#endif 


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
//MaximumInArrayUse.cpp

/************************************************************
        This is the file that holds the main function.      *
*************************************************************/

#include "MaximumInArray.h" //Requiring MaximuminArray.h
#include "MaximumInArray.cpp" //Requiring MaximumInArray.cpp
using namespace std;

int main() 
{
	// Array with doubles
	double doubles[] = {1.5, 4.6, 3.1, 1.1, 3.8};

	// Array with integers
	int integers[] = {2, 22, 4, 6, 122,};

	// Array with strings
	string strings[] = {"texas", "arizona", "oklahoma", "washington", "california"};

	// Checking the size of the double array
	const int doubleSize = sizeof doubles/sizeof doubles[0];
	// Show on the screen the maximum value of the array
	cout << "Maximum double in array is " << max(doubles, doubleSize) << endl; 

	// Checking the size of the double array
	const int integerSize = sizeof integers/sizeof integers[0];
	// Show on the screen the maximum value of the array
	cout << "Maximum integer in array is " << max(integers, integerSize) << endl;

	// Checking the size of the double array
	const int stringsSize = sizeof strings/sizeof strings[0];
	// Show on the screen the maximum value of the array
	cout << "Maximum string in array is " << max(strings, stringsSize) << endl;

	return 0;
}


Program Run:
1
2
3
4
Maximum double in array is 4.6
Maximum integer in array is 122
Maximum string in array is washington
Press any key to continue . . .    


I will try to get it working with vectors later... It's way too late for somebody who has a Calculus exam tomorrow XD Thanks once again for all your help.
Last edited on
Here are some functions that I've written which may help:

The first one will return the maximum from a vector of any type (as long as that type supports the < operator.
1
2
3
4
5
6
7
8
9
10
11
// Returns the maximum value from a range [first, last)
template <class Iter>
typename std::iterator_traits<Iter>::value_type
	MaxRange(Iter first, Iter last)
{
	typename std::iterator_traits<Iter>::value_type highVal = *first++;
	for ( ; first != last; ++first)
		if (highVal < *first)
			highVal = *first;
	return highVal;
}


This will will store a vector of a generic type (CountDownObject) so the same vector can hold templated objects who's types can be determined later.
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
struct CountDownObject
{
public:
    float m_timeLeft;
    virtual bool timeExpired(float dt) = 0;
};

template <typename T>
class DelayObject : public CountDownObject
{
private:
    T* m_address;
    T* m_target;
public:
    DelayObject( T* lpLabelAddress, float delay, T target)
    {
        m_address  = lpLabelAddress;
        m_target   = new T(target);
        m_timeLeft = delay;
    }

    // Decrements the timer and sets everything if required
    // Returns TRUE if the time has expired.  If this has happened, clean up DelayObject as it's useless now.
    virtual bool timeExpired(float dt)
    {
        m_timeLeft -= dt;

        if (m_timeLeft <= 0.0f)
        {
            *m_address = *m_target;
            delete m_target;
            return true;
        }
        return false;
    }
};

static std::vector<CountDownObject*> g_list;

template <typename T>
void SetAfterDelay     ( T* lpLabelAddress, float delay, T target = T(1) )
{
    g_list.push_back(new DelayObject<T>(lpLabelAddress, delay, target) );
}

void ManageDelays(float dt)
{
    for ( std::vector<CountDownObject*>::iterator it = g_list.begin(); it != g_list.end();)
    {
        if ( (*it)->timeExpired(dt) )
        {
            delete *it;
            it = g_list.erase(it);
        }
        else
            ++it;
    }
}
Wow, it works! Thanks a lot! I haven't learned structs yet though. I will look it up. Thanks!
Topic archived. No new replies allowed.