标准库中是否有与 std::thread 的构造函数语义匹配的类型擦除函数包装器?
Is there a type-erased function wrapper in the Standard Library that matches std::thread's constructor semantics?
我需要创建一个非模板类¹,该类需要保存可调用对象及其参数,以便稍后调用它们。
由于此类正在对异步执行进行建模,因此我想为其提供与std::thread
/std::async
匹配的 API 和语义:
class Async {
public:
template <typename Function, typename... Args >
explicit Async(Function&& f, Args &&... args)
{
// perform a (decay) copy of the args,
// store f and the copy somewhere
}
void call()
{
// to be possibly called in a different thread;
// call the function stored. no need to return the results
}
private:
// which data members?
};
我想到的第一件事是使用std::function<void()>
作为唯一的数据成员,并从参数的std::bind
初始化它。
但是,这不起作用:std::function
和std::bind
不支持仅移动类型,std::bind
在std::invoke
方面根本不起作用(它做了很多额外的魔术,比如递归解析绑定)。
我是否缺少标准库中提供的一些易于访问的解决方案来实现这一点,或者我应该部署自己的绑定器和类型擦除的函数包装类?
¹ 长话短说:此类需要从具有虚拟方法的基类继承,因此将此类设置为模板类会导致通常的代码膨胀和冲突,因为虚拟表和虚拟方法无处不在的重复。
template<class T> T&& wrap_pm(T&& t) { return std::forward<T>(t); }
template<class T, class U>
auto wrap_pm(U T::* p) -> decltype(std::mem_fn(p)) { return std::mem_fn(p); }
class Async {
public:
template <typename Function, typename... Args >
explicit Async(Function&& f, Args &&... args)
: fut(std::async(std::launch::deferred,
[f=std::forward<Function>(f)](auto&&... args) mutable
{
wrap_pm(std::move(f))(decltype(args)(args)...);
}, std::forward<Args>(args)...))
{ }
void call()
{
fut.get();
}
private:
std::future<void> fut;
};
我对效率不作任何承诺。
从技术上讲,std::packaged_task<void()>
符合您的要求。 这是严重的矫枉过正,因为它可以与线程交互并可以产生期货。
我写了一个处理仅移动调用的task
,它非常简单。 正确优化小型缓冲区更加困难。
class Async {
public:
template <typename Function, typename... Args >
explicit Async(Function&& f, Args &&... args) {
task = [f=std::forward<Function>(f), args=std::make_tuple(std::forward<Args>(args)...)]()mutable{
std::apply(std::move(f), std::move(args));
};
}
void call() {
task();
task={}; // don't call twice
}
private:
std::packaged_task<void()> task;
};
我用过的地方C++17 std 适用。 只需重新实现它,使用谷歌找到一个实现。
相关文章:
- 在运行时处理类型擦除的数据-如何不重新发明轮子
- 类型擦除的std::function与虚拟函数调用的开销
- 如何在C++中允许成员函数的自定义返回类型进行类型擦除?
- 如何投射类型擦除的 std::function?
- 类型擦除代码的依赖注入单元测试
- 标准库中是否有与 std::thread 的构造函数语义匹配的类型擦除函数包装器?
- 类型擦除和一种模板方法模式
- 在小对象优化中调试崩溃以进行类型擦除
- 带有模板复制和移动构造函数的C++类型擦除
- C++技术:类型擦除与纯多态性
- 使用类型擦除创建运行时type_traits查询
- 类型擦除是否有效取决于优化级别
- 转换为类型擦除的元组
- 如何实现像 std::function 这样的自毁类型擦除类
- unique_ptr类型擦除析构函数不能正常工作(带有警告)
- 什么是C++中的类型擦除
- C++类型擦除,请使用 std::function 捕获单个类的多个方法
- Boost类型擦除的实践和发现
- 现代C++中的类型擦除分配器
- c++类型擦除/类型封装?发现类型