How can I include templates in a program divided into multiple files?

Hello everyone. I made a program that gets a series of integers and stores them in an object of the vector class, then I call a function to sort them and then another one to show the new ordered vector. What I want to know is how I could use a template to make this program rather than just accept integers, accept a generic type 'T'. I've tried creating templates in many ways, but I do not know where I should put them and where I should not put them.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// main.cpp
#include <iostream>
#include <vector>
#include "vector.h"

using namespace std;

int main ()
{
	vector <int> v;
	int x;

	while (cin >> x)
	{
		v.push_back(x);
	}

	insertion_sort (v); // Function to order the vector
	display(v); // Function to display the values of vector

}


1
2
3
4
5
6
7
8
9
10
11
12
13
// vector.h
#ifndef _VECTOR_H_
#define _VECTOR_H_ 

using namespace std;


void insertion_sort (vector<int>& vec);
void display (vector<int>& vec);


#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
// vector.cpp
#include <iostream>
#include <vector>
#include "vector.h"

using namespace std;

void insertion_sort (vector <int>& vec)
{
	int j, temp;
	for (int i=1; i<vec.size(); i++)
	{
		j=i;
		while (j>0 and vec[j-1]>vec[j]) 
		{
			temp=vec[j];
			vec[j] = vec[j-1];
			vec[j-1] = temp;
			j--;
		}
	}
}


void display (vector<int>& vec)
{
	for (int i=0;i<vec.size();i++)
	{
		cout << vec[i] << " ";
	}
}
Last edited on
When using templates all template code must reside in a header file. You can't have any of the template code(Declaration and Definition) in a source file.

So you have a few options,one would be to implement both your insertion_sort() and display() functions completely in your vector.h header file and that should work fine with templates.

The other way if you want to break up the declaration and definition of your template function is to use two header files like so.

SomeFile.hpp
1
2
3
4
5
6
7
8
9
10
11
12
#ifndef SOME_FILE_HPP
#define SOME_FILE_HPP

// We declare our template here
template <typename T>
void mySortFunction(std::vector<T>& vec);

// This line is key, we are basically saying put the contents of SomeFile.inl right where this 
// include is.
#include "SomeFile.inl"

#endif 


SomeFile.inl (The .inl extension is a common extension used for template definition, but you can use really any extension you want as long as it is not a .cpp or .c file)
1
2
3
4
5
6
7
8
9
10
11
12
13
#ifndef SOME_FILE_INL
#define SOME_FILE_INL

// Here is where we define our template function, we don't need to include SomeFile.hpp 
// in this file because the contents in SomeFile.inl are basically just going to be copied and 
// pasted into the SomeFile.hpp file at the #include line.
template <typename T>
void mySortFunction(std::vector<T>& vec)
{
    // Do some stuff here.
}

#endif 


It's up to you what way you want to do it. Both are perfectly legal and have their uses, sometimes you can deal with everything being in a single header file, while other times you want the separation to make things more organized.

Also please ignore any syntax mistakes in the above examples if there is any, don't have access to a compiler here so was doing it all inline in the post ;p.
Last edited on
Templates are implemented in the header file:
http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file
http://stackoverflow.com/questions/5612791/c-template-and-header-files

your second function has to
show the new ordered vector
– one option is to #include <iostream> in the header/implementation file and call the ostream object std::cout in the header file itself while defining this function – however it is a good idea to try and avoid including the iostream header file within your header file(s) as this it is large and slows down compilation.

An alternative is to use #include <iosfwd> which contains forward declarations for the input/output library:
http://en.cppreference.com/w/cpp/header/iosfwd
http://stackoverflow.com/questions/4300696/what-is-the-iosfwd-header
the following program follows this alternative approach:
Header+Implementation
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
#ifndef TEST_HEADER
#define TEST_HEADER

#include <vector>
#include <algorithm>
#include <iosfwd>

template <typename T>
std::vector<T> sortVec(std::vector<T>& myVec)
{
    std::sort(myVec.begin(), myVec.end());
    return myVec;
}

template <typename T>
void showVec(const std::vector<T>& myVec, std::ostream& os)
{
    os << "Sorted vector: \n";
    for (const auto& elem : myVec)
    {
        os << elem << " ";
    }
    os << "\n";
}

#endif // TEST_HEADER 

Main Program
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include "test_header.h"
#include <iostream>
#include <vector>
#include <algorithm>


int main()
{
    std::cout << "How many elements: \n";
    size_t dimension{};
    std::cin >> dimension;
    size_t i{};
    std::vector<int> myVec{};
    while (i < dimension)
    {
        std::cout << "Enter element " << i+1 << " of " << dimension << "\n";
        int num{};
        std::cin >> num;
        myVec.push_back(num);
        ++i;
    }
    sortVec(myVec);
    showVec(myVec, std::cout);
}

Last edited on
@gunnerfunner

Thanks. This solved my problem.
Topic archived. No new replies allowed.