Is it possible to create a general method or class that can be used to create β€œnew” instances of any class?

Usually, if I have Foo or Bar , I would do something like:

 Foo* foo = new Foo(); Bar* bar = new Bar(2,3,5); 

Is there a way to use templates or macros so that I can build a function so that I can do something like:

 Foo* foo = MyAwesomeFunc(Foo); Bar* bar = MyAwesomeFunc(Bar,2,3,5); 

The actual signature of the MyAwesomeFunc method is not important to me.

Foo and Bar should not be connected in any way possible and may have completely different constructors. In addition, I can support any number of classes in the future without actually modifying the MyAwesomeFunc code

Is it possible? A simple way would be to inherit both Foo and Bar from some type, say Baz , and overloaded methods return the Baz that you return to Foo or Bar ...

 Baz* MyAwesomeFunc(){ return new Foo(); } Baz* MyAwesomeFunc(int a,int b,int c){ return new Bar(a,b,c); } 

But the problems are here - you have to write:

  • method for each supported class
  • and for each type of constructor signature.

The goal is to write a single class, method or macro where we can call one function (and pass any arguments to it), but call the constructor of the passed object on the right. Is it possible?

The purpose of this question is simply to examine whether it is possible to do something similar in C ++. Please do not pick up generic pointers, unique pointers, traps for using new ones, as this is off topic.

EDIT: I would like to use only STL and avoid using things like Boost ....

+6
source share
2 answers

With C ++ 11 you can do this with a variation pattern and perfect forward . For instance. write a template function that ideally passes its parameters to the constructor of the object with the type specified by the template parameter.

 template <typename T, typename... Ts> T* MyAwesomeFunc(Ts&&... params){ return new T(std::forward<Ts>(params)...); } 

Then use it like

 Foo* foo = MyAwesomeFunc<Foo>(); Bar* bar = MyAwesomeFunc<Bar>(2,3,5); 
+8
source

Yes you can use templates and C ++ 11 "Perfect Forwarding":

 #include <type_traits> #include <utility> template<typename T, typename... Args> T* createNew(Args&&... args) { static_assert(std::is_constructible<T, Args...>::value, "T is not constructible with these arguments"); return new T(std::forward<Args>(args)...); } 

Alternatively, you can check C ++ 11 std::make_unique and "Smart Pointers" What is a smart pointer and when should I use it?

+8
source

Source: https://habr.com/ru/post/1014826/


All Articles