Это подпись std::make_unique
template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&...);
Когда вы указали Args
, как и вы, std::make_unique
может принимать только значения. Однако std::bind
передает свои связанные аргументы как lvalues, поэтому вы получаете ошибку.
Вместо std::bind
вместо лямбды
template<typename...>
struct pack {};
template<typename T, typename Tup, typename... TArgs, std::size_t... Is>
std::unique_ptr<T> helper(Tup&& tup, pack<TArgs...>, std::index_sequence<Is...>)
{
return std::make_unique<T>(static_cast<TArgs>(std::get<Is>(tup))...);
}
template <typename T>
class ConstructLater
{
public:
template<typename... Args>
ConstructLater(Args&&... args)
: factory{[tup = std::make_tuple(std::forward<Args>(args)...)]() mutable {
return helper<T>(std::move(tup), pack<Args&&...>{}, std::index_sequence_for<Args...>{});
}}
{
}
std::unique_ptr<T> Later()
{
return factory();
}
private:
std::function<std::unique_ptr<T>(void)> factory;
};
Заметьте также, что ConstructLater
не должен быть шаблоном Args
, он уничтожает всю цель std::function
. В любом случае, сам конструктор должен быть настроен на шаблон для полной пересылки его аргументов.