Is there a way to write make_unique() in VS2012?

前端 未结 6 1357
情书的邮戳
情书的邮戳 2020-12-03 07:44

Herb Sutter propose a simple implementation of make_unique() there: http://herbsutter.com/gotw/_102/

Here it is:

template

        
6条回答
  •  爱一瞬间的悲伤
    2020-12-03 08:43

    You could use Boost.Preprocessor to generate the different parameter counts, but I really don't see the advantage of that. Simply do the grunt job once, stuff it in a header and be done. You're saving yourself compile time and have your make_unique.

    Here's a copy-paste of my make_unique.h header that simulates variadic templates for up to 5 arguments.


    Since OP seems to not like copy-paste work, here's the Boost.Preprocessor code to generate the above:

    First, make a main header that includes the template header multiple times (Boost.Preprocessor iteration code blatantly stolen from this answer):

    // make_unique.h
    #include 
    #include 
    #include 
    
    #ifndef MAKE_UNIQUE_NUM_ARGS
    // allow this to be changed to a higher number if needed,
    // ten is a good default number
    #define MAKE_UNIQUE_NUM_ARGS 10
    #endif
    
    #if MAKE_UNIQUE_NUM_ARGS < 0
    // but don't be stupid with it
    #error Invalid MAKE_UNIQUE_NUM_ARGS value.
    #endif
    
    /* optional, see above for premade version
    // include premade functions, to avoid the costly iteration
    #include "detail/blah_premade.hpp
    
    // generate classes if needed
    #if MAKE_UNIQUE_NUM_ARGS > MAKE_UNIQUE_NUM_PREMADE
    */
    #define BOOST_PP_ITERATION_LIMITS (0, MAKE_UNIQUE_NUM_ARGS)
    #define BOOST_PP_FILENAME_1 "make_unique_template.h"
    #include BOOST_PP_ITERATE()
    //#endif
    

    And now make a template header that gets included again and again and expands differently depending on the value of MAKE_UNIQUE_NUM_ARGS:

    // make_unique_template.h
    // note: no include guard
    
    #define N BOOST_PP_ITERATION()    
    
    #define MAKE_UNIQUE_TEMPLATE_PARMS \
      BOOST_PP_ENUM_PARAMS(N, typename A)
    
    #define MAKE_UNIQUE_FUNCTION_PARM(J,I,D) \
      BOOST_PP_CAT(A,I)&& BOOST_PP_CAT(a,I)
    
    #define MAKE_UNIQUE_FUNCTION_PARMS \
      BOOST_PP_ENUM(N, MAKE_UNIQUE_FUNCTION_PARM, BOOST_PP_EMPTY)
    
    #define MAKE_UNIQUE_ARG(J,I,D) \
      std::forward(BOOST_PP_CAT(a,I))
    
    #define MAKE_UNIQUE_ARGS \
      BOOST_PP_ENUM(N, MAKE_UNIQUE_ARG, BOOST_PP_EMPTY)
    
    template
    std::unique_ptr make_unique(MAKE_UNIQUE_FUNCTION_PARMS){
      return std::unique_ptr(new T(MAKE_UNIQUE_ARGS));
    }
    
    // clean up
    #undef MAKE_UNIQUE_TEMPLATE_PARMS
    #undef MAKE_UNIQUE_FUNCTION_PARM
    #undef MAKE_UNIQUE_FUNCTION_PARMS
    #undef MAKE_UNIQUE_ARG
    #undef MAKE_UNIQUE_ARGS
    #undef N
    

提交回复
热议问题