undefined reference to `std::vector<int, std::allocator<int> >

R

rethnor

ok, I need some help here as I'm lost as to what is wrong. I've never
really used templates nor the std library before and I am trying to
learning on a quicksort sample. so to cut to the chase here is the
code I'm using, there are three files.

my compiler version is 4.2.1-dw2 (ming32-2)

Any direction would be helpful and apricated, thanks.

compiler error:
g++ -O2 -g -Wall -c -fmessage-length=0 -osrc\QuickSort.o ..\src
\QuickSort.cpp
g++ -O2 -g -Wall -c -fmessage-length=0 -osrc\boosttest.o ..\src
\boosttest.cpp
g++ -oboosttest.exe src\boosttest.o src\QuickSort.o -lboost_thread
src\boosttest.o: In function `main':
C:\dev\workspace\boosttest\Release/../src/boosttest.cpp:85: undefined
reference to `std::vector<int, std::allocator<int> >
QuickSort<int>(std::vector<int, std::allocator<int> >)'
collect2: ld returned 1 exit status

QuickSort.cpp:
#include "QuickSort.hpp"

template<class T>
T GetPivot(vector<T> data) {
return data[(int)data.size()/2];
}

template<class T>
void Partition( vector<T> data,
vector<T> &left,
vector<T> &right) {

T pivot = GetPivot<T>(data);

for(int i = 0; i < data.size(); i++) {
if(data < pivot)
left.push_back(data);
else if(data >= pivot)
right.push_back(data);
}
}

template<class T>
vector<T> Join(vector<T> &left, vector<T> &right) {
left.insert(left.end(), right.begin(), right.end());
return left;
}

template<class T>
vector<T> QuickSort(vector<T> data) {
if(data.size() <= 1)
return data;
vector<T> left;
vector<T> right;

Partition(data, left, right);
left = QuickSort<T>(left);
right = QuickSort<T>(right);

return Join<T>(left, right);
}

void printHello() {
std::cout << "Hello world!" << std::endl;
}

QuickSort.hpp:
#ifndef QUICKSORT_HPP_
#define QUICKSORT_HPP_

#include <vector>
#include <iostream>

using std::vector;

// returns the pivot point
// Pre
template<typename T>
T GetPivot(vector<T> data);

// Partitions the values from data into two new vectors
template<typename T>
void Partition( vector<T> data,
vector<T> &left,
vector<T> &right);

// Concatenates the right vector onto the end of the left vector
template<typename T>
vector<T> Join(vector<T> &left, vector<T> &right);

// Entry Call to quicksort
template<typename T>
vector<T> QuickSort(vector<T> data);


#endif /*QUICKSORT_HPP_*/

boosttest.cpp:
// Boost includes
#include <boost/thread/thread.hpp>
#include <boost/thread/xtime.hpp>
#include <boost/random/linear_congruential.hpp>
#include <boost/random/uniform_int.hpp>
#include <boost/random/variate_generator.hpp>

// ODE includes
#include <ode/ode.h>

// STD includes
#include <iostream>
#include <vector>
#include <string>

// UserDefined Includes
#include "QuickSort.hpp"

const int NSECONDS = 1;
const int USECONDS = 1000 * NSECONDS;
const int MSECONDS = 1000 * USECONDS;
const int SECONDS = 1000 * MSECONDS;
const int MINUTE = 60 * SECONDS;

const int NUM_THREADS = 10;

// This is a typedef for a random number generator.
// Try boost::mt19937 or boost::ecuyer1988 instead of
boost::minstd_rand
typedef boost::minstd_rand base_generator_type;

// container for the delay
std::vector<int> delays;

// mutex for accessing the delay vector
boost::mutex delay_mutex;


void sleep(int time) {
boost::xtime xt;
boost::xtime_get(&xt, boost::TIME_UTC);
xt.sec += time;

boost::thread::sleep(xt);
}

//"worker" function, this does all the sleeping, the lazy bastard!
void hello_world()
{
int delay;
{
boost::mutex::scoped_lock lock(delay_mutex);
delay = delays.back();
delays.pop_back();
std::cout << "Good night world, I'm sleeping for "
<< delay << " seconds!!" << std::endl;
}
// perform the sleep outside of scope so it doesn't pause the
other threads
sleep(delay);

std::cout << "YAWN!!! I just woke up from sleeping for "
<< delay << " seconds." << std::endl;

}

int main(int argc, char* argv[])
{
// Generate the random numbe generator
base_generator_type generator(67u);
//boost::mt19937 rng; // produces randomness out of
thin air
// see pseudo-random number
generators
boost::uniform_int<> ten(1,12); // distribution that maps to
1..10
// see random number
distributions
// glues randomness with
mapping
boost::variate_generator<
base_generator_type&,
boost::uniform_int<> > delay_time(generator, ten);

// populate the delay with 10 random number
for(int i = 0; i < 10; i++) {
boost::mutex::scoped_lock lock(delay_mutex);
delays.push_back(delay_time());
}

delays = QuickSort<int>(delays);

// start a new thread that calls the "hello_world" function
boost::thread my_thread0(&hello_world);
boost::thread my_thread1(&hello_world);
boost::thread my_thread2(&hello_world);
boost::thread my_thread3(&hello_world);
boost::thread my_thread4(&hello_world);
boost::thread my_thread5(&hello_world);
boost::thread my_thread6(&hello_world);
boost::thread my_thread7(&hello_world);
boost::thread my_thread8(&hello_world);
boost::thread my_thread9(&hello_world);

my_thread0.join();
my_thread1.join();
my_thread2.join();
my_thread3.join();
my_thread4.join();
my_thread5.join();
my_thread6.join();
my_thread7.join();
my_thread8.join();
my_thread9.join();

return 0;
}
 
R

Rolf Magnus

ok, I need some help here as I'm lost as to what is wrong. I've never
really used templates nor the std library before and I am trying to
learning on a quicksort sample. so to cut to the chase here is the
code I'm using, there are three files.

The implementation of a template must be visible where the compiler needs to
instantiate it. The simplest way to do that is instead of linking to your
template implementation .cpp file, to #include it at the end of your
header.
 
R

rethnor

(e-mail address removed) wrote:
The implementation of a template must be visible where the compiler needs to
instantiate it. The simplest way to do that is instead of linking to your
template implementation .cpp file, to #include it at the end of your
header.

So really, I should just implement my functions in the header file
rather than in a separate cpp file. would the same apply to classes
instead of functions?
 
R

rethnor

(e-mail address removed) wrote:
The implementation of a template must be visible where the compiler needs to
instantiate it. The simplest way to do that is instead of linking to your
template implementation .cpp file, to #include it at the end of your
header.

So really, I should just implement my functions in the header file
rather than in a separate cpp file. would the same apply to classes
instead of functions?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top