Every problem can be solved by adding one more layer.
First lets isolate the job of Factory. It should do only one task. Factory provides an interface on top on the underlying object of type T.
template <typename T>
class Factory
{
public:
// prefer copy and move, if you have C++11
Factory(Type d) : data(std::move(d)) {}
// const getter
T get() const { return data; };
// non-const reference getter, for modifications
T & get() { return data; };
private:
T data;
};
Now lets create a helper function on top of it, to help us manage and allocate objects. The job of this MakeObject is to make an object and hand over the object to a manager, i.e. Factory. It then returns the instance of that managed object.
template<typename Object, typename ... Args>
Factory<Object> MakeObject(Args && ... args)
{
return Factory<Object>{ Object{ std::forward<Args>(args) ... } };
}
Now we can combine the two of them independently, to create something that is desired.
#include <iostream>
template <typename T>
class Factory
{
public:
Factory(Type d) : data(std::move(d)) {}
T get() const { return data; };
T & get() { return data; };
private:
T data;
};
template<typename Object, typename ... Args>
Factory<Object> MakeObject(Args && ... args)
{
return Factory<Object>{ Object{ std::forward<Args>(args) ... } };
}
struct book
{
std::string name;
int phone;
book(std::string s, int t) : name(s), phone(t) {}
};
void print(Factory<book> const & k)
{
std::cout << "[ Factory ] : " << k.get().name << ", " << k.get().phone << std::endl;
}
int main()
{
auto obj = MakeObject<book>("Hello World", 91520);
print(obj);
return 0;
}
I didn't use the static function CreateBook because the intent is not clear. If you really want to use static, now you have the decoupled code, and it can be implemented and tested independently in the class Factory.