我有一个ThreadPool
类,其中包含enqueue
函数:
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和assignment操作符。该程序不再编译,因为可变参数模板按值而不是通过引用获取其参数。
所以我声明enqueue通过引用传递可变参数模板参数:
template <typename ... Args, typename Fun>
JobId enqueue(Fun func, Args&... args);
现在不再调用复制构造函数,但是我收到以下错误:
object.cpp:21:错误:没有用于调用
的匹配函数'ThreadPool :: enqueue(bool(Object :: *)(const PrepareData&amp;),Object *, const PrepareData&amp;)' threadPool-&gt; enqueue(&amp; prepareType,this,loadStuff);
所以我很失落如何做到这一点。我可以,而不是通过const PrepareData &
传递const PrepareData *
副本,但我想理解为什么它不能用const引用。
答案 0 :(得分:1)
此:
var brandClass
// Iterate though split classes
jQuery.each( classList, function(i) {
if ( classList[i].includes('product-wildridge') ) {
brandClass = classList[i];
}
});
// check specific class for certin keywords
var customTab = function(brandClass) {
if (brandClass.includes('wildridge') && brandClass.includes('deep') ) {
return true;
} else {
jQuery('#tab-fabric').css('display', 'none');
}
}
customTab(brandClass);
复制所有template <typename ... Args, typename Fun>
JobId enqueue(Fun func, Args ... args);
,因为它们全部按值传递。对于参数传递的工作原理似乎有些混淆 - 你通过引用const来调用args
并不重要,重要的是enqueue
通过值来获取它的参数。 enqueue
以引用方式传递,但init()
不是。
您可能想要的是将引用包装器传递给您的数据(按值):
enqueue()
这样可以避免复制threadPool->enqueue(&loadStuff, this, std::ref(prepareData));
并正确调用prepareData
。这也使loadStuff()
的调用者有责任知道应该复制哪些内容以及应该引用哪些内容。
虽然enqueue()
需要确保QObject
持续足够长的时间。我们参考prepareData
来看待它,所以它似乎没有办法做到这一点。因此,或许另一种方法是const
按值获取数据:
init()