If you don't want overloading, and want to be able to specialize from a separate file, then I think you should base it on the solution on the link from your question. It involves making a static method on a class that you specialize. From my reading of the question, you're only interested in specializing on the T
, not on the number of arguments, which you intend to forward. In C++11, you can do the following:
#include <iostream>
#include <utility>
using namespace std;
template<typename T>
struct factory_impl;
// Left unspecified for now (which causes compliation failure if
// not later specialized
template<typename T, typename... Args>
T create(Args&&... args)
{
return factory_impl<T>::create(std::forward<Args>(args)...);
}
// Note, this can be specified in a header in another translation
// unit. The only requirement is that the specialization
// be defined prior to calling create with the correct value
// of T
template<>
struct factory_impl<int>
{
// int can be constructed with 0 arguments or 1 argument
static int create(int src = 0)
{
return src;
}
};
int main(int argc, char** argv)
{
int i = create<int>();
int j = create<int>(5);
// double d = create<double>(); // Fails to compile
std::cout << i << " " << j << std::endl;
return 0;
}
Live example http://ideone.com/7a3uRZ
Edit: In response to your question, you could also make create
a member function of a class, and pass along some of that data with the call or take action before or after
struct MyFactory
{
template<typename T, typename... Args>
T create(Args&&... args)
{
T ret = factory_impl<T>::create(data, std::forward<Args>(args)...);
// do something with ret
return ret;
}
Foo data; // Example
};