C++模板 - 可变参数模板和路过常引用
我有一个ThreadPool
类的enqueue
功能:C++模板 - 可变参数模板和路过常引用
class ThreadPool
{
public:
//(Code removed here)
template <typename ... Args, typename Fun>
JobId enqueue(Fun func, Args ... args);
//(Code removed here)
}
我用它在这些非静态成员函数loadStuff
上Object
类:
class Object
{
//(Code removed here)
void init(const PrepareData & prepareData);
virtual bool loadStuff(const PrepareData & prepareData);
//(Code removed here)
}
通过调用QObject :: init:
void QObject::init(const PrepareData &prepareData)
{
threadPool->enqueue(&loadStuff, this, prepareData);
}
但我注意到prepareData是通过复制传递的,这会消耗大量的内存并显着减慢程序的速度(并且是无用的)。
所以我删除了PrepareData中的copy ctor和赋值操作符。该程序不再编译,因为可变参数模板通过值而不是参考来获取参数。
因此,我宣布排队按引用传递的可变参数模板参数:
template <typename ... Args, typename Fun>
JobId enqueue(Fun func, Args&... args);
现在拷贝构造函数不再被调用,但我得到以下错误:
object.cpp:21: error: no matching function for call to
'ThreadPool::enqueue(bool (Object::*)(const PrepareData&), Object *, const PrepareData&)' threadPool->enqueue(&prepareType, this, loadStuff);
所以我如何做到这一点,我相当遗憾。我可以,而不是通过const PrepareData &
,通过const PrepareData *
副本,但我想了解为什么它不适用于const引用。
此:
template <typename ... Args, typename Fun>
JobId enqueue(Fun func, Args ... args);
复制所有args
,因为他们都按值传递。对于参数传递如何工作似乎存在一些混淆 - 无论您是否在调用const时引用enqueue
都没关系,重要的是enqueue
通过值取其参数。 init()
是通过参考,但enqueue()
不是。
你可能就要什么是(按价值计算)传递一个参考包装到您的数据:
threadPool->enqueue(&loadStuff, this, std::ref(prepareData));
这将避免复制prepareData
和正确调用loadStuff()
。这也使enqueue()
的调用者有责任知道应该复制哪些东西以及应该引用哪些东西。
虽然QObject
需要确保prepareData
持续足够长的。我们通过参考const
,所以它似乎没有任何方式做到这一点。所以,或许是另一种方法是有init()
按值取其数据:
void QObject::init(PrepareData prepareData)
{
threadPool->enqueue(&loadStuff, this, std::move(prepareData));
}
说'参数数量&& ...'。 –