Hi,
I'm trying to write a simple Queue class, but I'm having trouble using it. It tells me I have undefined references to the functions I call in main.

// main.cpp
#include <iostream>
#include "queue.h"

void main()
{

Queue<int> myq;

myq.push(10);
std::cout << myq.isempty() << endl;
myq.makeempty();
std::cout << myq.isempty() << endl;
}
// queue.h
#include <vector>

using namespace std;

template <typename U>
class Queue
{
public:
  void push(U const &);
  void pop();
  bool isempty();
  void makeempty();
private:
   vector<U>info;
};
// queue.cpp
template <typename T> void Queue<T>::push(T const & tmp)
{
  info.push_back(tmp);
}

template <typename T> void MyQueue<T>::pop()
{
  info.erase(info.begin(), info.begin() + 1);
}

template <typename T> bool isempty()
{
  return (info.empty());
}

template <typename T> void makeempty()
{
  info.erase(info.begin(), info.end());    
}

Any ideas?

Recommended Answers

All 11 Replies

Hello,

"Undefined symbol" errors result from the linker unable to find the actual code for a function, even if it's been defined. This means that there is a problem with your preprocessor commands.

Try adding a #include "queue.h" to queue.cpp.

In queue.h, you should have this added to avoid multiple inclusion errors:

// add this to top of file
#ifndef QUEUE_H
#define QUEUE_H
// classes go here

// footer
#endif

Hopefully this should get rid of the undefined symbol errors!

Can I combine Queue.h and Queue.cpp into one file? I tried it, but I still get errors, so I'm not sure if that is allowed.

It's possible to put member function implementations in the class header source file, but it's generally discouraged, and the compiler may produce code bloat.

Have you tried what I suggested? Did it work?

It's possible to put member function implementations in the class header source file, but it's generally discouraged, and the compiler may produce code bloat.

Have you tried what I suggested? Did it work?

I did try it, but no luck :sad: same errors.

Alright, I read the page a few times, and tested a few things and still I was frustrated. I decided to do away with the templates, because in my case I am only going to use it for int. I simplified my .h and .cpp file. I've also found that if I change my main() to do nothing except initialize the class and call it myQueue, it works fine. But, when I try to use myQueue.push(10); , I get

/tmp/ccrYIuoY.o: In function `main':
/tmp/ccrYIuoY.o(.text+0x28): undefined reference to `Queue::push(int const &)'
collect2: ld returned 1 exit status

Hey there nanodano, dont you think you are overlookign something.

The syntax for templates is template < class T > and not template < typename T > Try to make the following change in your files and see if it works.

Ok, so I tried everything I could think of and tried everyone's suggestions. Finally, I just put it all into my main cpp file. It looks like this:

#include <iostream>
#include <vector>

class Queue
{
public:
  void push(int const & tmp) { info.push_back(tmp); }
  void pop() { info.erase(info.begin(), info.begin()+1); }
  bool isempty() { return (info.empty()); }
  void makeempty() { info.erase(info.begin(), info.end()); }
private:
   std::vector<int>info;
};

void main()
{
  Queue myq;

  myq.push(10);
  std::cout << myq.isempty() << endl;
  myq.makeempty();
  std::cout << myq.isempty() << endl;
}

It's definately more compact code...but it works.

Right,

as an example if you were using gcc youw oul need to do something like:

gcc -o output main.cpp queue.cpp

you are getting an undefined ref because it does not know how to link them....

this should allow you to put them in separate files

Member Avatar for iamthwee

Using header files are easy.

Most IDE's do the compilation for you so you don't have to
use

gcc -o output main.cpp queue.cpp

at the command line.

Are both files in the same directory?

>void main()
I'll just get this out of the way. void main is incorrect. The correct definition of main is int main() .

>The syntax for templates is
>template < class T >
>and not
>template < typename T >
Both are correct. As a template parameter, class and typename have the same meaning. Your suggested change would do nothing.

>Any ideas?
You can't separate the template declaration and defintions. The export keyword was added to the standard for this, but it's extremely difficult to implement (not to mention the semantics are very tricky) and not many compilers support it in any useful fashion.

>undefined reference to `Queue::push(int const &)'
How are you building this? What compiler and OS are you using?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.