C++ templated function causing linking errors

This is a discussion on C++ templated function causing linking errors within the C++ Programming forums, part of the General Programming Boards category; class mergeSort.cpp Code: #include <iostream> #include <vector> #include "mergeSortContainer.cpp" using namespace std; template void merge<vector<int>::iterator>(vector<int>::iterator begin, vector<int>::iterator mid, vector<int>::iterator end, ...

  1. #1
    Registered User
    Join Date
    Nov 2010
    Posts
    7

    C++ templated function causing linking errors

    class mergeSort.cpp
    Code:
    #include <iostream>
    #include <vector>
    #include "mergeSortContainer.cpp"
    
    using namespace std;
    
    template void merge<vector<int>::iterator>(vector<int>::iterator begin, vector<int>::iterator mid, vector<int>::iterator end, bool (*compare)(int &x, int &y));
    
    template void mergeSort<vector<int>::iterator>(vector<int>::iterator begin, vector<int>::iterator end, bool (*compare)(int &x, int &y));
    
    bool exCompare(int &a, int &b);
    
    bool exCompare(int &a, int &b) {
        return (a<b);
    }
    
    int main(){
        vector<int> vec;
        vec.push_back(5);
        vec.push_back(7);
        vec.push_back(6);
        vector<int>::iterator it = vec.begin();
        vector<int>::iterator it2 = vec.end();
    
        mergeSort<vector<int>::iterator>(it, it2, exCompare);
        return 0;
    }
    class mergeSortContainer.cpp:
    Code:
    #include <iostream>
    
    using namespace std;
    
    template <typename I>
    void merge(I begin, I mid, I end, bool (*compare)(typename I::value_type &x, typename I::value_type &y)) {
    
        //Get the lengths of the left and the right part.
        int n1 = mid - begin;
        int n2 = end - mid;
    
        typedef typename I::value_type T;
        T* left = new T[n1];
        T* right = new T[n2];
        int i;
    
        //populate left and right arrays
        i = 0;
        for (I p=begin;i<n1;p++) {
            left[i] = *p;
            i++;
        }
        i = 0;
        for (I p=(mid);i<n2;p++) {
            right[i] = *p;
            i++;
        }
        
    
        T* result;
        i = 0;
        int leftCtr = 0;
        int rightCtr = 0;
    
        //Merge the two sorted arrays 
        for (;i<n1+n2;i++) {
            if (leftCtr<n1 && rightCtr<n2) {
                if (compare(left[leftCtr],right[rightCtr])) {
                    result[i] = left[leftCtr++];
                }
                else result[i] = right[rightCtr++];
            }
            else if (leftCtr<n1)
                result[i] = left[leftCtr++];
            else
                result[i] = right[rightCtr++];
        }
        i = 0;
    
        //Copy the sorted array back into the original array.
        for (I p=begin;p!=end;p++) {
            *p = result[i++];
        }
    }
                
                
    
    template<typename I>
    void mergeSort(I begin, I end, bool (*compare)(typename I::value_type &x, typename I::value_type &y)) {
    
        int len = end - begin;
    
        if (len>1) {
            I mid = begin + len/2;
            
            //Sort both the halves
            mergeSort(begin, mid, compare);
            mergeSort(mid, end, compare);
            merge(begin, mid, end, compare);
        }
    
        return;
    }
    when I compile this program I get a long list of what appear to be linker errors. I am using a linux gcc compiler. Any ideas of how I can fix this?
    Last edited by coder123321; 11-17-2010 at 02:33 PM.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    23,624
    Move the definitions of your function templates to your header file. You could also read How can I avoid linker errors with my template functions?

    EDIT:
    Actually, it does look like you are using the latter technique. Fascinating.
    Last edited by laserlight; 11-17-2010 at 02:33 PM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Nov 2010
    Posts
    7
    What do you mean by that? Should I just change mergeSortContainer.cpp to .h? I have read that article you refer to and tried both suggestions and neither one seems to work.

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    23,624
    Quote Originally Posted by coder123321
    Should I just change mergeSortContainer.cpp to .h?
    Yes, that is one way, but of course you should also then properly make it a header file, and remove these from mergeSort.cpp:
    Code:
    template void merge<vector<int>::iterator>(vector<int>::iterator begin, vector<int>::iterator mid, vector<int>::iterator end, bool (*compare)(int &x, int &y));
    
    template void mergeSort<vector<int>::iterator>(vector<int>::iterator begin, vector<int>::iterator end, bool (*compare)(int &x, int &y));
    Quote Originally Posted by coder123321
    I have read that article you refer to and tried both suggestions and neither one seems to work.
    The first suggestion is precisely what I suggested: place the function template definition in the header file. I realised that you did not actually implement the second suggestion. Rather, these lines should be placed at the bottom of mergeSortContainer.cpp:
    Code:
    template void merge<vector<int>::iterator>(vector<int>::iterator begin, vector<int>::iterator mid, vector<int>::iterator end, bool (*compare)(int &x, int &y));
    
    template void mergeSort<vector<int>::iterator>(vector<int>::iterator begin, vector<int>::iterator end, bool (*compare)(int &x, int &y));
    Then you forward declare (not include) in mergeSort.cpp:
    Code:
    template <typename I>
    void merge(I begin, I mid, I end, bool (*compare)(typename I::value_type &x, typename I::value_type &y));
    
    template<typename I>
    void mergeSort(I begin, I end, bool (*compare)(typename I::value_type &x, typename I::value_type &y));
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    Nov 2010
    Posts
    7
    I tried your suggestions/retried implementing the tutorial instructions and to no avail. here is the current code, which gives me the same linker errors

    Code:
    //mergeSort.cpp
    #include <iostream>
    #include <vector>
    #include "mergeSortContainer.h"
    
    using namespace std;
    
    template <typename I>
    void merge(I begin, I mid, I end, bool (*compare)(typename I::value_type &x, typename I::value_type &y));
    
    template<typename I>
    void mergeSort(I begin, I end, bool (*compare)(typename I::value_type &x, typename I::value_type &y));
    
    bool exCompare(int &a, int &b);
    
    bool exCompare(int &a, int &b) {
    	return (a<b);
    }
    
    int main(){
    	vector<int> vec;
    	vec.push_back(5);
    	vec.push_back(7);
    	vec.push_back(6);
    	vector<int>::iterator it = vec.begin();
    	vector<int>::iterator it2 = vec.end();
    	mergeSort<vector<int>::iterator>(it, it2, exCompare);
    
    
    	return 0;
    }
    Code:
    //mergeSortContainer.h
    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    template <typename I>
    void merge(I begin, I mid, I end, bool (*compare)(typename I::value_type &x, typename I::value_type &y));
    
    template<typename I>
    void mergeSort(I begin, I end, bool (*compare)(typename I::value_type &x, typename I::value_type &y));
    
    #include "mergeSortContainer.cpp"
    Code:
    //mergeSortContainer.cpp
    template <typename I>
    void merge(I begin, I mid, I end, bool (*compare)(typename I::value_type &x, typename I::value_type &y)) {
    
    	//Get the lengths of the left and the right part.
    	int n1 = mid - begin;
    	int n2 = end - mid;
    
    	typedef typename I::value_type T;
    	T* left = new T[n1];
    	T* right = new T[n2];
    	int i;
    
    	//populate left and right arrays
    	i = 0;
    	for (I p=begin;i<n1;p++) {
    		left[i] = *p;
    		i++;
    	}
    	i = 0;
    	for (I p=(mid);i<n2;p++) {
    		right[i] = *p;
    		i++;
    	}
    
    
    	T* result;
    	i = 0;
    	int leftCtr = 0;
    	int rightCtr = 0;
    
    	//Merge the two sorted arrays
    	for (;i<n1+n2;i++) {
    		if (leftCtr<n1 && rightCtr<n2) {
    			if (compare(left[leftCtr],right[rightCtr])) {
    				result[i] = left[leftCtr++];
    			}
    			else result[i] = right[rightCtr++];
    		}
    		else if (leftCtr<n1)
    			result[i] = left[leftCtr++];
    		else
    			result[i] = right[rightCtr++];
    	}
    	i = 0;
    
    	//Copy the sorted array back into the original array.
    	for (I p=begin;p!=end;p++) {
    		*p = result[i++];
    	}
    }
    
    
    
    template<typename I>
    void mergeSort(I begin, I end, bool (*compare)(typename I::value_type &x, typename I::value_type &y)) {
    
    	int len = end - begin;
    
    	if (len>1) {
    		I mid = begin + len/2;
    
    		//Sort both the halves
    		mergeSort(begin, mid, compare);
    		mergeSort(mid, end, compare);
    		merge(begin, mid, end, compare);
    	}
    
    	return;
    }
    
    template void merge<vector<int>::iterator>(vector<int>::iterator begin, vector<int>::iterator mid, vector<int>::iterator end, bool (*compare)(int &x, int &y));
    template void mergeSort<vector<int>::iterator>(vector<int>::iterator begin, vector<int>::iterator end, bool (*compare)(int &x, int &y));

  6. #6
    Registered User
    Join Date
    Nov 2010
    Posts
    7
    heres the error i get:
    Code:
    gcc mergeSort.cpp -o mergeSort
    mergeSort.cpp: In function `int main()':
    mergeSort.cpp:22: error: no matching function for call to `mergeSort(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >&, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >&, bool (&)(int&, int&))'
    student@eecs280-student-vm:~/workspace/Project4$ gcc mergeSort.cpp -o mergeSort
    mergeSort.cpp: In function `int main()':
    mergeSort.cpp:21: error: no matching function for call to `mergeSort(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >&, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >&, bool (&)(int&, int&))'
    student@eecs280-student-vm:~/workspace/Project4$ gcc mergeSort.cpp -o mergeSort
    mergeSort.cpp: In function `int main()':
    mergeSort.cpp:21: error: no matching function for call to `mergeSort(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >&, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >&, bool (*)(int&, int&))'
    student@eecs280-student-vm:~/workspace/Project4$ gcc mergeSort.cpp -o mergeSort
    /tmp/ccokdOWu.o: In function `std::__verify_grouping(char const*, unsigned int, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)':
    mergeSort.cpp:(.text+0xd): undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::size() const'
    mergeSort.cpp:(.text+0x60): undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator[](unsigned int) const'
    mergeSort.cpp:(.text+0x9e): undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator[](unsigned int) const'
    mergeSort.cpp:(.text+0xcc): undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator[](unsigned int) const'
    /tmp/ccokdOWu.o: In function `__static_initialization_and_destruction_0(int, int)':
    mergeSort.cpp:(.text+0x261): undefined reference to `std::ios_base::Init::Init()'
    /tmp/ccokdOWu.o: In function `__tcf_0':
    mergeSort.cpp:(.text+0x292): undefined reference to `std::ios_base::Init::~Init()'
    /tmp/ccokdOWu.o: In function `void merge<__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > > >(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, bool (*)(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >::value_type&, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >::value_type&))':
    mergeSort.cpp:(.gnu.linkonce.t._Z5mergeIN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEEEvT_S7_S7_PFbRNS7_10value_typeES9_E+0x3c): undefined reference to `operator new[](unsigned int)'
    mergeSort.cpp:(.gnu.linkonce.t._Z5mergeIN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEEEvT_S7_S7_PFbRNS7_10value_typeES9_E+0x4d): undefined reference to `operator new[](unsigned int)'
    /tmp/ccokdOWu.o: In function `std::vector<int, std::allocator<int> >::_M_insert_aux(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, int const&)':
    mergeSort.cpp:(.gnu.linkonce.t._ZNSt6vectorIiSaIiEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPiS1_EERKi+0x1cb): undefined reference to `__cxa_begin_catch'
    mergeSort.cpp:(.gnu.linkonce.t._ZNSt6vectorIiSaIiEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPiS1_EERKi+0x207): undefined reference to `__cxa_rethrow'
    mergeSort.cpp:(.gnu.linkonce.t._ZNSt6vectorIiSaIiEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPiS1_EERKi+0x212): undefined reference to `__cxa_end_catch'
    /tmp/ccokdOWu.o: In function `__gnu_cxx::new_allocator<int>::deallocate(int*, unsigned int)':
    mergeSort.cpp:(.gnu.linkonce.t._ZN9__gnu_cxx13new_allocatorIiE10deallocateEPij+0xd): undefined reference to `operator delete(void*)'
    /tmp/ccokdOWu.o: In function `__gnu_cxx::new_allocator<int>::allocate(unsigned int, void const*)':
    mergeSort.cpp:(.gnu.linkonce.t._ZN9__gnu_cxx13new_allocatorIiE8allocateEjPKv+0x10): undefined reference to `operator new(unsigned int)'
    /tmp/ccokdOWu.o:(.eh_frame+0x12): undefined reference to `__gxx_personality_v0'
    collect2: ld returned 1 exit status
    student@eecs280-student-vm:~/workspace/Project4$ gcc mergeSort.cpp mergeSortContainer.cpp -o mergeSort
    mergeSort.cpp: In function `int main()':
    mergeSortContainer.h:12: error: `mergeSortContainer<I>::mergeSortContainer() [with I = __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >]' is private
    mergeSort.cpp:21: error: within this context
    mergeSortContainer.h:13: error: `mergeSortContainer<I>::~mergeSortContainer() [with I = __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >]' is private
    mergeSort.cpp:21: error: within this context
    mergeSortContainer.cpp:61: error: `void mergeSortContainer<I>::mergeSort(I, I, bool (*)(typename I::value_type&, typename I::value_type&)) [with I = __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >]' is private
    mergeSort.cpp:22: error: within this context
    mergeSortContainer.cpp:8: error: expected initializer before '<' token
    mergeSortContainer.cpp:61: error: expected initializer before '<' token
    student@eecs280-student-vm:~/workspace/Project4$ gcc mergeSort.cpp -o mergeSort
    mergeSort.cpp: In function `int main()':
    mergeSortContainer.h:12: error: `mergeSortContainer<I>::mergeSortContainer() [with I = __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >]' is private
    mergeSort.cpp:21: error: within this context
    mergeSortContainer.h:13: error: `mergeSortContainer<I>::~mergeSortContainer() [with I = __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >]' is private
    mergeSort.cpp:21: error: within this context
    mergeSortContainer.cpp:61: error: `void mergeSortContainer<I>::mergeSort(I, I, bool (*)(typename I::value_type&, typename I::value_type&)) [with I = __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >]' is private
    mergeSort.cpp:22: error: within this context
    student@eecs280-student-vm:~/workspace/Project4$ gcc mergeSort.cpp -o mergeSort
    /tmp/ccoXie7L.o: In function `std::__verify_grouping(char const*, unsigned int, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)':
    mergeSort.cpp:(.text+0xd): undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::size() const'
    mergeSort.cpp:(.text+0x60): undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator[](unsigned int) const'
    mergeSort.cpp:(.text+0x9e): undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator[](unsigned int) const'
    mergeSort.cpp:(.text+0xcc): undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator[](unsigned int) const'
    /tmp/ccoXie7L.o: In function `main':
    mergeSort.cpp:(.text+0x1f6): undefined reference to `mergeSortContainer<__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > > >::mergeSortContainer()'
    mergeSort.cpp:(.text+0x222): undefined reference to `mergeSortContainer<__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > > >::~mergeSortContainer()'
    mergeSort.cpp:(.text+0x247): undefined reference to `mergeSortContainer<__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > > >::~mergeSortContainer()'
    /tmp/ccoXie7L.o: In function `__static_initialization_and_destruction_0(int, int)':
    mergeSort.cpp:(.text+0x295): undefined reference to `std::ios_base::Init::Init()'
    /tmp/ccoXie7L.o: In function `__tcf_0':
    mergeSort.cpp:(.text+0x2c6): undefined reference to `std::ios_base::Init::~Init()'
    /tmp/ccoXie7L.o: In function `std::vector<int, std::allocator<int> >::_M_insert_aux(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, int const&)':
    mergeSort.cpp:(.gnu.linkonce.t._ZNSt6vectorIiSaIiEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPiS1_EERKi+0x1cb): undefined reference to `__cxa_begin_catch'
    mergeSort.cpp:(.gnu.linkonce.t._ZNSt6vectorIiSaIiEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPiS1_EERKi+0x207): undefined reference to `__cxa_rethrow'
    mergeSort.cpp:(.gnu.linkonce.t._ZNSt6vectorIiSaIiEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPiS1_EERKi+0x212): undefined reference to `__cxa_end_catch'
    /tmp/ccoXie7L.o: In function `mergeSortContainer<__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > > >::merge(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, bool (*)(int&, int&))':
    mergeSort.cpp:(.gnu.linkonce.t._ZN18mergeSortContainerIN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEEE5mergeES6_S6_S6_PFbRiS8_E+0x3c): undefined reference to `operator new[](unsigned int)'
    mergeSort.cpp:(.gnu.linkonce.t._ZN18mergeSortContainerIN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEEE5mergeES6_S6_S6_PFbRiS8_E+0x4d): undefined reference to `operator new[](unsigned int)'
    /tmp/ccoXie7L.o: In function `__gnu_cxx::new_allocator<int>::deallocate(int*, unsigned int)':
    mergeSort.cpp:(.gnu.linkonce.t._ZN9__gnu_cxx13new_allocatorIiE10deallocateEPij+0xd): undefined reference to `operator delete(void*)'
    /tmp/ccoXie7L.o: In function `__gnu_cxx::new_allocator<int>::allocate(unsigned int, void const*)':
    mergeSort.cpp:(.gnu.linkonce.t._ZN9__gnu_cxx13new_allocatorIiE8allocateEjPKv+0x10): undefined reference to `operator new(unsigned int)'
    /tmp/ccoXie7L.o:(.eh_frame+0x12): undefined reference to `__gxx_personality_v0'
    collect2: ld returned 1 exit status

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    23,624
    I suggest that you try this:
    Code:
    //mergeSort.cpp
    #include <iostream>
    #include <vector>
    #include "mergeSortContainer.h"
    
    using namespace std;
    
    bool exCompare(int &a, int &b);
    
    bool exCompare(int &a, int &b) {
    	return (a<b);
    }
    
    int main(){
    	vector<int> vec;
    	vec.push_back(5);
    	vec.push_back(7);
    	vec.push_back(6);
    	vector<int>::iterator it = vec.begin();
    	vector<int>::iterator it2 = vec.end();
    	mergeSort<vector<int>::iterator>(it, it2, exCompare);
    
    
    	return 0;
    }
    Code:
    #ifndef MERGESORTCONTAINER_H_
    #define MERGESORTCONTAINER_H_
    
    //mergeSortContainer.h
    
    template <typename I>
    void merge(I begin, I mid, I end, bool (*compare)(typename I::value_type &x, typename I::value_type &y));
    
    template<typename I>
    void mergeSort(I begin, I end, bool (*compare)(typename I::value_type &x, typename I::value_type &y));
    
    #endif
    Code:
    //mergeSortContainer.cpp
    template <typename I>
    void merge(I begin, I mid, I end, bool (*compare)(typename I::value_type &x, typename I::value_type &y)) {
    
    	//Get the lengths of the left and the right part.
    	int n1 = mid - begin;
    	int n2 = end - mid;
    
    	typedef typename I::value_type T;
    	T* left = new T[n1];
    	T* right = new T[n2];
    	int i;
    
    	//populate left and right arrays
    	i = 0;
    	for (I p=begin;i<n1;p++) {
    		left[i] = *p;
    		i++;
    	}
    	i = 0;
    	for (I p=(mid);i<n2;p++) {
    		right[i] = *p;
    		i++;
    	}
    
    
    	T* result;
    	i = 0;
    	int leftCtr = 0;
    	int rightCtr = 0;
    
    	//Merge the two sorted arrays
    	for (;i<n1+n2;i++) {
    		if (leftCtr<n1 && rightCtr<n2) {
    			if (compare(left[leftCtr],right[rightCtr])) {
    				result[i] = left[leftCtr++];
    			}
    			else result[i] = right[rightCtr++];
    		}
    		else if (leftCtr<n1)
    			result[i] = left[leftCtr++];
    		else
    			result[i] = right[rightCtr++];
    	}
    	i = 0;
    
    	//Copy the sorted array back into the original array.
    	for (I p=begin;p!=end;p++) {
    		*p = result[i++];
    	}
    }
    
    
    
    template<typename I>
    void mergeSort(I begin, I end, bool (*compare)(typename I::value_type &x, typename I::value_type &y)) {
    
    	int len = end - begin;
    
    	if (len>1) {
    		I mid = begin + len/2;
    
    		//Sort both the halves
    		mergeSort(begin, mid, compare);
    		mergeSort(mid, end, compare);
    		merge(begin, mid, end, compare);
    	}
    
    	return;
    }
    
    #include <vector>
    
    using std::vector;
    
    template void merge<vector<int>::iterator>(vector<int>::iterator begin, vector<int>::iterator mid, vector<int>::iterator end, bool (*compare)(int &x, int &y));
    template void mergeSort<vector<int>::iterator>(vector<int>::iterator begin, vector<int>::iterator end, bool (*compare)(int &x, int &y));
    Note that I remove the inclusion of mergeSortContainer.cpp from mergeSortContainer.h since you appear to be using the second method, hence you will compile mergeSortContainer.cpp. I also added header inclusion guards and removed the unnecessary header inclusions and using directive. The #include <vector> was shifted to mergeSortContainer.cpp instead, with a using declaration added. Oh, and since mergeSortContainer.h already forward declares the function templates, those forward declarations were removed from mergeSort.cpp.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Registered User
    Join Date
    Nov 2010
    Posts
    7
    Thanks alot the code finally compiled. I think the issue was mostly related to the way I was trying to compile. I was simply calling gcc mergeSort.cpp mergeSortContainer.cpp -o mergeSort, but when I used eclipse to compile everything went according to plan. How could I go about avoiding this linking issue when making a custom makefile?
    Last edited by coder123321; 11-18-2010 at 10:56 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Compiling GNU MP
    By mattnp12 in forum C Programming
    Replies: 3
    Last Post: 06-23-2011, 03:58 PM
  2. dllimport function not allowed
    By steve1_rm in forum C++ Programming
    Replies: 5
    Last Post: 03-11-2008, 03:33 AM
  3. doubt in c parser coding
    By akshara.sinha in forum C Programming
    Replies: 4
    Last Post: 12-23-2007, 12:49 PM
  4. We Got _DEBUG Errors
    By Tonto in forum Windows Programming
    Replies: 5
    Last Post: 12-22-2006, 04:45 PM
  5. Flood of errors when include .h
    By erik2004 in forum C++ Programming
    Replies: 14
    Last Post: 12-07-2002, 06:37 AM

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