How to work with 10 limits for make_shared in Visual Studio

When using the new C ++ 10 functions on some old code, I ended up with a problem that I cannot call make_shared , which takes 12 parameters. I remember how Microsoft STL talked about how they use emulation for make_shared and that 10 is the maximum. Obviously, the refactoring code just for this is out of the question, so basically my question is: is there a way to get more than 10 parameters before make_shared in VS 2010.

+4
source share
2 answers
 make_shared<foobar>(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12); 

can be replaced by

 shared_ptr<foobar>(new foobar(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)); 

In C ++ 11, std :: make_shared actually represents a performance optimization when creating an object using the second method, since it only performs one memory allocation instead of two, but as soon as you get 10 variables, you don't have much choice as to what use.

+11
source

If you really want to use make_shared for your performance benefits, you can still do this:

 #include <tuple> #include <memory> #include <redi/index_tuple.h> template<typename X, typename... Args> std::shared_ptr<X> make_shared_TO_THE_MAX(Args&&... args) { struct Wrapper { X x; template<typename... T> Wrapper(std::tuple<T...> targs) : Wrapper(targs, to_index_tuple<T...>{}) { } template<typename T, unsigned... I> Wrapper(T targs, index_tuple<I...>) : x(std::get<I>(targs)) { } }; auto wrapped = std::make_shared<Wrapper>(std::forward_as_tuple(std::forward<Args>(args)...)); return std::shared_ptr<X>(wrapped, &wrapped->x); } 

This combines the constructor arguments into a link tuple and passes it to make_shared , so it doesn’t matter that make_shared cannot handle 10 arguments because it only gets one. Instead of make_shared<X> it uses make_shared<Wrapper> , which allocates space for Wrapper (which is the same size and layout as its member of type X ), and builds it using a tuple of arguments. The Wrapper constructor delegates to another constructor, which extends the tuple to go to the X constructor.

Finally, it uses the shared_ptr anti-aliasing constructor to return shared_ptr<X> , which has ownership of shared_ptr<Wrapper> but retains the address of the X object.

<redi/index_tuple.h> my own header , but I'm trying to get something like that standardized for C ++ 14.

This can be done without variation patterns, but it works more. Here it is for two arguments, just add ten more for twelve!

 #include <tuple> #include <memory> template<typename X, typename Arg0, typename Arg1> std::shared_ptr<X> make_shared_TO_THE_MAX(Arg0&& arg0, Arg1&& arg1) { struct Wrapper { X x; template<typename T0, typename T1> Wrapper(std::tuple<T0, T1> targs) : x(std::get<0>(targs), std::get<1>(targs)) { } }; auto wrapped = std::make_shared<Wrapper>(std::forward_as_tuple(std::forward<Arg0>(arg0), std::forward<Arg1>(arg1))); return std::shared_ptr<X>(wrapped, &wrapped->x); } 
+1
source

All Articles