1

I am trying to design a worker and a task class and am having some trouble with getting it right. The basic design that I have implemented is

class Result{
    void isComplete()
    void cancel()
    ...
}

class Task{
    Result Submit()
    ...
}

I want to create a version of these where I can also return an object in the result. Like this,

template<typename T>
class Result : Result{
    T* GetResult();
}

template<typename T>
class Task : Task {
    void SetResult(T* result);
}

what is the best way to achieve this? I was thinking of creating a class with void as a default parameter but am not sure if void can be passed into a method as an argument.

randomThought
  • 6,203
  • 15
  • 56
  • 72
  • @Bathsheba I might be returning a unique_ptr instead since the caller would own the memory. Once a "Task" is completed, it no longer owns memory – randomThought Jun 30 '14 at 09:23
  • http://stackoverflow.com/questions/4638956/why-is-this-default-template-parameter-not-allowed – didierc Jun 30 '14 at 09:23
  • http://stackoverflow.com/questions/13372173/using-void-template-arguments-in-c – didierc Jun 30 '14 at 09:24
  • `void` actually is somewhat ambivalent in C//C++, since it may represent the empty type, but as such you cannot use it for parameter types as is. Otoh, it may be used in `void *`, ie the pointer to some unidentified type. Usage in templates is predicated by how the type is used internally: if you use a `T *` inside your template, you may bind `T` to `void` for instance, because the resulting type is legitimate. – didierc Jun 30 '14 at 09:29
  • That said, I don't see any major issue with your design. You might want to look at [`std::future`](http://en.cppreference.com/w/cpp/thread/future) from C++11 for inspiration. – didierc Jun 30 '14 at 09:41
  • Note that It seems that programmers.stackexchange.com is a better fit for design related questions. – didierc Jun 30 '14 at 09:45

1 Answers1

1

You are right that void cannot be "passed as argument". However, in your case you pass a pointer to T as the argument, so it would be void*, which is a valid argument type. But it still would not make much sense having a method taking a void-pointer to nothing if there is no result object. So you could specialize the templates for void and get rid of the methods for that case, e.g. like this:

template<typename T>
class Task : public TaskBase {
  void SetResult(T* result);
  // other methods
};

template <>
class Task<void> : public TaskBase {
  //only the other methods
};

Note that you will have difficulties trying to implement a template class Task and a nontemplate class with the same name. The compiler will not be able to distinguish those names.

Arne Mertz
  • 24,171
  • 3
  • 51
  • 90