1

I'd like to create my own template class for Thread. As template arguments I'd like to set: function to be called when thread starts, class of parameter passed to the previously defined function, function to be called after thread ends and class of parameter returned by previous function.

So I want something like this:

In header file:

template<typename taskClass, typename taskDataClass, typename endCallbackClass, typename endCallbackDataClass>
class Thread {
public:
  Thread();

private:
  bool mIsActive;
  bool mIsDone;
  pthread_t mPThread;
  taskClass mTask;
  taskDataClass mTaskData;
  endCallbackClass mEndCallback;
  endCallbackDataClass mEndCallbackData;
}

In cpp file:

#include "Thread.h"

template<typename taskClass, typename taskDataClass, typename endCallbackClass, typename endCallbackDataClass>
Thread<taskClass, taskDataClass, endCallbackClass, endCallbackDataClass>::Thread() {

}

However creating an instance of such class causes troubles:

auto th = new Thread<std::function<void(bool)>, bool, std::function<void(int)>, int>();

Error is:

undefined reference to `Thread<std::function<void (bool)>, bool, std::function<void (int)>, int>::Thread()' 

Can anybody explain to me what is the problem in this case? I don't see the problem...

karlkar
  • 227
  • 1
  • 5
  • 12
  • 2
    Private constructor (but I don't understand the error in that case). Where's that code? In a header file? Do you actually have your implementation in a cpp file? – Marco A. Apr 20 '15 at 13:51
  • You didn't happen to put the actual implementation of the constructor somewhere other than in a header? – molbdnilo Apr 20 '15 at 13:55
  • I have this code in 2 files - cpp and h. I've changed the code a bit not to add both files in here. However in cpp file constructor implementation is empty. – karlkar Apr 20 '15 at 14:07

2 Answers2

3

The code you posted has a private constructor

template<typename taskClass, typename taskDataClass, typename endCallbackClass, typename endCallbackDataClass>
class Thread {
    Thread() {};
    ^^^^^^

but the problem is a linking error: in the comments you stated that

I have this code in 2 files - cpp and h. I've changed the code a bit not to add both files in here. However in cpp file constructor implementation is empty.

It doesn't matter if the constructor is empty: since templates code needs to be available at compile-time (i.e. before translation units actually see each other), you need to either:

  • Make your implementation code available in the header file
  • Explicitly instantiate the code for the types you're going to use

Recommended reading: Why can templates only be implemented in the header file?

Community
  • 1
  • 1
Marco A.
  • 43,032
  • 26
  • 132
  • 246
0
template<typename taskClass, typename taskDataClass, typename endCallbackClass, typename endCallbackDataClass>
class Thread {
public:
    Thread() {};
private:
    bool mIsActive;
    bool mIsDone;
    int mPThread;  //use msvc 
    taskClass mTask;
    taskDataClass mTaskData;
    endCallbackClass mEndCallback;
    endCallbackDataClass mEndCallbackData;
};

int main()
{
    auto th = new Thread<std::function<void(bool)>, bool, std::function<void(int)>, int>();
}

Works! you forgot public constructor

jen6
  • 68
  • 8