#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>
{
// Call 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;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dXRpbGl0eT4KdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCgp0ZW1wbGF0ZTx0eXBlbmFtZSBUPgpzdHJ1Y3QgZmFjdG9yeV9pbXBsOyAKLy8gTGVmdCB1bnNwZWNpZmllZCBmb3Igbm93ICh3aGljaCBjYXVzZXMgY29tcGxpYXRpb24gZmFpbHVyZSBpZiAKLy8gbm90IGxhdGVyIHNwZWNpYWxpemVkCgp0ZW1wbGF0ZTx0eXBlbmFtZSBULCB0eXBlbmFtZS4uLiBBcmdzPgpUIGNyZWF0ZShBcmdzJiYuLi4gYXJncykKewogICAgcmV0dXJuIGZhY3RvcnlfaW1wbDxUPjo6Y3JlYXRlKHN0ZDo6Zm9yd2FyZDxBcmdzPihhcmdzKS4uLik7Cn0KCgovLyBOb3RlLCB0aGlzIGNhbiBiZSBzcGVjaWZpZWQgaW4gYSBoZWFkZXIgaW4gYW5vdGhlciB0cmFuc2xhdGlvbgovLyB1bml0LiAgVGhlIG9ubHkgcmVxdWlyZW1lbnQgaXMgdGhhdCB0aGUgc3BlY2lhbGl6YXRpb24gCi8vIGJlIGRlZmluZWQgcHJpb3IgdG8gY2FsbGluZyBjcmVhdGUgd2l0aCB0aGUgY29ycmVjdCB2YWx1ZQovLyBvZiBUCnRlbXBsYXRlPD4Kc3RydWN0IGZhY3RvcnlfaW1wbDxpbnQ+CnsKICAgIC8vIENhbGwgd2l0aCAwIGFyZ3VtZW50cyBvciAxIGFyZ3VtZW50CiAgICBzdGF0aWMgaW50IGNyZWF0ZShpbnQgc3JjID0gMCkKICAgIHsKICAgICAgICByZXR1cm4gc3JjOwogICAgfQp9OwoKaW50IG1haW4oaW50IGFyZ2MsIGNoYXIqKiBhcmd2KQp7CiAgICBpbnQgaSA9IGNyZWF0ZTxpbnQ+KCk7CiAgICBpbnQgaiA9IGNyZWF0ZTxpbnQ+KDUpOwogICAgLy8gZG91YmxlIGQgPSBjcmVhdGU8ZG91YmxlPigpOyAvLyBGYWlscyB0byBjb21waWxlCgogICAgc3RkOjpjb3V0IDw8IGkgPDwgIiAiIDw8IGogPDwgc3RkOjplbmRsOwogICAgcmV0dXJuIDA7Cn0K