I have an application class that can take in a dependent class as a template argument to the constructor. This dependent class is required to provide certain templated functions that the application class can call. I would like to offload this dependent class object to a pimpl class so the application class is not a template class and thus header-only.
Here is a rough idea of what I mean.
///////////
// impl.h
///////////
template<typename Helper>
struct Impl
{
public:
Impl(Helper& helper) : helper_(helper)
{
}
template <typename T>
void someHelperFn1(T t)
{
helper_->fn1(t);
}
template <typename U>
SomeOtherClass<U> someHelperFn2()
{
return helper_->fn2();
}
private:
Helper& helper_;
};
///////////
// app.h
///////////
#include "impl.h"
class App
{
public:
template<typename Helper>
App(Helper &h) :impl_(new Impl) {}
template <typename T>
void someHelperFn1(T t)
{
impl_->someHelperFn1(t);
}
template <typename U>
SomeOtherClass<U> someHelperFn2()
{
return impl_->someHelperFn2();
}
void someAppFn();
private;
std::unique_ptr<Impl> impl_;
};
///////////
// app.cpp
///////////
void App::someAppFn()
{
// some useful code
}
I realize the above code doesn't compile since Impl is really a template class and so App would also be a template class too. That is what I would like to avoid so that App is not a header-only class. I found something similar except the functions that I want to call from the helper dependency are template functions and they are not in this case. It seemed pretty close otherwise to what I wanted to do.
Any ideas on how I can avoid making App a template class?
I tried making the helper class use a common base class but that is not really possible with the template functions.
Also, note that I am limited to C++ 17 for the compiler.
You will need to make sure the public header file (the one with the class that has the pimpl pointer) doesn't expose the header file only class template of the implementation. Use an interface for that like this. I did not dependency inject the implementation because that should not be needed.