我需要一个可用作延迟工厂的类,保存参数以创建另一个类,并稍后调用make_unique。到目前为止,我没有运气来获取可变参数模板版本。任何帮助,将不胜感激(下面的最小无效版本)。
template <typename T, typename ... Args>
class ConstructLater
{
public:
ConstructLater(Args &&... args)
{
factory = std::bind(std::make_unique<T, Args...>, std::forward<Args>(args)...);
}
std::unique_ptr<T> Later()
{
return factory();
}
private:
std::function<std::unique_ptr<T>(void)> factory;
};
class Foo { public: Foo(int) { } };
int f()
{
// None of these work
ConstructLater<Foo>(3);
ConstructLater<Foo, int>(6);
}
编辑:为澄清起见,我不需要使用std :: bind,实际上我希望类按值存储参数的副本,以避免临时对象出现问题。还将标签更新为C ++ 14。
这是 std::make_unique
template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&...);
当Args
像您一样指定时,std::make_unique
可能只接受右值。但是,std::bind
将其绑定参数作为左值传递,这就是为什么会出现错误的原因。
代替std::bind
,使用lambdas代替
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
。无论哪种方式,都需要对构造函数本身进行模板化,以完美转发其参数。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句