Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
142 views
in Technique[技术] by (71.8m points)

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

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

Here it is:

template<typename T, typename ...Args>
std::unique_ptr<T> make_unique( Args&& ...args )
{
    return std::unique_ptr<T>( new T( std::forward<Args>(args)... ) );
}

My problem is that variadic templates are not yet part of VS2012, so I can't use this code as is.

Is there a maintainable way to write this in VS2012 that wouldn't involve copy-pasting the same function with different args count?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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 <memory>
#include <utility>
#include <boost/preprocessor.hpp>

#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)>(BOOST_PP_CAT(a,I))

#define MAKE_UNIQUE_ARGS 
  BOOST_PP_ENUM(N, MAKE_UNIQUE_ARG, BOOST_PP_EMPTY)

template<class T BOOST_PP_COMMA_IF(N) MAKE_UNIQUE_TEMPLATE_PARMS>
std::unique_ptr<T> make_unique(MAKE_UNIQUE_FUNCTION_PARMS){
  return std::unique_ptr<T>(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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

56.9k users

...