在这种情况下如何正确使用std转发



这里有一个类,它将队列作为私有成员和addTask((方法,当我编译它时,我遇到了std::forward:错误

#include <iostream>
#include <unistd.h>
#include <functional>
#include <vector>
#include <thread>
#include <condition_variable>
#include <queue>
#include <future>
#include <memory>
#include <utility>
class Pool {
public:
using Task = std::function<void()>;
Pool(){}
~Pool(){}
template<typename Func, typename ...Args>
auto addTask(Func task, Args &&... arguments) -> std::future<decltype(task(arguments...))>
{
auto wrapper = std::make_shared<std::packaged_task<decltype(task(arguments...)) (Args...)>>(std::move(task));
{
std::unique_lock<std::mutex> lock(mEventMutex);
mTasks.emplace([=] {
(*wrapper)(std::forward<Args...>(arguments...));
});
}
return wrapper->get_future();         
}
private:
std::queue<Task> mTasks;
std::mutex mEventMutex;
};

并像这样使用它:

int task_with_argument(int value)
{
return value;
}
addTask( task_with_argument, 10 );

我得到错误:

error: no matching function for call to ‘forward(const int&)’

我也试过这个:

(*wrapper)(std::forward<Agrs>(arguments)...);

再次出现错误:

error: binding reference of type ‘std::remove_reference<int>::type&’ {aka ‘int&’} to ‘const int’ discards qualifiers

哪里有问题?

此调用:

std::forward(arguments...)

不是使用CCD_ 1的正确方式。

相反,您应该将函数的参数作为转发引用:

addTask(Func task, Args &&... arguments)

然后使用这样的参数:

std::forward<Args...>(arguments...)

您试图应用完美转发,但这在您的问题解决方案中没有意义。为了隐藏一个任务及其所有参数,必须制作这些参数的副本。这会挫败所有完美的转发尝试。

此外,您要求std::future存储一个decltype(task(arguments...),即选择一个在没有完全转发参数的情况下调用的重载。至少可以说,用完全转发的参数进行实际调用是不一致的(如果这有意义的话(。

只需移除std::forward:

mTasks.emplace([=] { (*wrapper)(arguments...); });

最新更新