Я заинтересован в написании лямбда-функции, которая, помимо прочего, будет вызывать std::make_unique
. Для вызова std::make_unique
мне нужно имя типа, но может показаться, что для того, чтобы напрямую передать имя типа в лямбда-функцию, мне пришлось бы сделать лямбда-переменную шаблоном:
struct SpecialThing
{
SpecialThing(/* some arguments */) {}
}
void f()
{
template <typename Thing>
auto createThing = [](auto&&... parameters)
{
return std::make_unique<Thing>(std::forward<decltype(parameters)>(parameters)...);
};
auto thing = createThing<SpecialThing>(/* some construction parameters */);
}
Но моему компилятору (GCC 4.9.2) это не нравится. (На самом деле я этого не ожидал, хотя я достаточно мало знаю о переменных шаблона, поэтому не мог быть уверен, что это не так.)
Предположим, я действительно решил сохранить createThing
локальную переменную типа лямбда-функции. Насколько чисто я смогу таким образом обернуть std::make_unique
? Вот лучшее, что у меня есть на данный момент:
void f()
{
auto createThing = [](auto dummyThingPointer, auto&&... parameters)
{
typedef typename std::remove_pointer<decltype(dummyThingPointer)>::type Thing;
return std::make_unique<Thing>(std::forward<decltype(parameters)>(parameters)...);
};
auto thing = createThing(static_cast<SpecialThing*>(nullptr), /* some construction parameters */);
}
Это многословно, но его не так уж сложно понять, и он компилируется.
Я думаю, что, возможно, я мог бы сделать что-то подобное с std::declval
и std::remove_reference
, но я не мог скомпилировать это. В любом случае это было бы не намного чище, чем указано выше.
Предоставляет ли C ++ 14 какой-нибудь незаметный способ превратить тип SpecialThing
в createThing
? Или, если это не удастся, хитрый способ лучше моего трюка с nullptr?
(Примечание: я знаю, что могу обойти это другими способами; я просто прошу изучить язык, а не преодолеть серьезное препятствие. Отсюда глупый код выше, который банально оборачивает стандартную функцию без видимой причины.)