有没有办法在VS2012中编写make_unique()?

Kla*_*aim 16 c++ templates unique-ptr variadic-templates c++11

Herb Sutter提出了一个简单的实现make_unique():http://herbsutter.com/gotw/_102/

这里是:

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

我的问题是可变参数模板还不是VS2012的一部分,所以我不能按原样使用这个代码.

有没有一种可维护的方法在VS2012中写这个不会涉及使用不同的args计数复制粘贴相同的函数?

Xeo*_*Xeo 14

您可以使用Boost.Preprocessor生成不同的参数计数,但我真的没有看到它的优点.只需做一次咕噜咕噜的工作,把它塞进标题然后完成.你节省了自己的编译时间并拥有你的make_unique.

是我的make_unique.h标题的复制粘贴,模拟最多5个参数的可变参数模板.


由于OP似乎不喜欢复制粘贴工作,这里是生成上述内容的Boost.Preprocessor代码:

首先,多次创建一个包含模板头的主头(Boost.Preprocessor迭代代码从这个答案中公然被盗):

// 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
Run Code Online (Sandbox Code Playgroud)

现在制作一个模板标题,一次又一次地包含,并根据以下值进行不同的扩展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
Run Code Online (Sandbox Code Playgroud)


Hug*_*ues 8

尽管可变参数模板不是VS2012的一部分,但是头文件<memory>中内置了一些宏来帮助模拟它们.

看到这个非常好的答案,它展示了如何make_unique<T>在几条神秘的线条中实现.我确认它运作良好:

#include <memory> // brings in TEMPLATE macros.
#define MAKE_UNIQUE(TEMPLATE_LIST, PADDING_LIST, LIST, COMMA, X1, X2, X3, X4)   \
  template<class T COMMA LIST(_CLASS_TYPE)>  \
  inline std::unique_ptr<T> make_unique(LIST(_TYPE_REFREF_ARG))  \
  {  \
      return std::unique_ptr<T>(new T(LIST(_FORWARD_ARG)));  \
  }
_VARIADIC_EXPAND_0X(MAKE_UNIQUE, , , , )
#undef MAKE_UNIQUE
Run Code Online (Sandbox Code Playgroud)