Create a shared maker stateless function object class, like std::less
, but with no template
parameters itself: instead operator()
perfect forwards to your template
function.
Pass it instead of your function pointer.
If you need template
arguments passed to it, either create a static
method to it, or make the entire template class
take the arguments and use them in the operator()
.
Here is an example of late-bound template
arguments (live example):
#include <iostream>
// test stubs:
template<typename... Ts>
using UPtr = int;
template<typename... Ts>
using SPtr = double;
template<typename T, typename...TA>
UPtr<T,TA...> makeUniquePtr() {
std::cout << "makeUniquePtr\n";
return {};
}
template<typename T, typename...TA>
SPtr<T,TA...> makeSharedPtr() {
std::cout << "makeSharedPtr\n";
return {};
}
// perfect forwarding make static functions passed by class name:
struct unique_ptr_maker {
template<typename T, typename...TA, typename...Args>
static UPtr<T, TA...> make(Args&&...args) {
return makeUniquePtr<T, TA...>( std::forward<Args>(args)... );
}
};
struct shared_ptr_maker {
template<typename T, typename...TA, typename...Args>
static SPtr<T, TA...> make(Args&&...args) {
return makeSharedPtr<T, TA...>( std::forward<Args>(args)... );
}
};
// your `func`. It can take args or whatever:
template<typename maker, class T, class... TA> void func() {
std::cout << "func\n";
maker::template make<T, TA...>();
}
// a sample of implementation 1 and 2:
template<class T, class... TA> void implementation1()
{
func<unique_ptr_maker, T, TA...>();
}
template<class T, class... TA> void implementation2()
{
func<shared_ptr_maker, T, TA...>();
}
// and, to test, always instantiate:
int main() {
implementation1<int, double>();
implementation2<int, char>();
return 0;
}
with much of the functionality stubbed out, as you did not detail what it was supposed to do in your question.