我想生成一个线程或调用此函数的未来:
std::string myClass::myFunction() const noexcept
我首先尝试像这样生成它们:
thread t0(myFunction); auto f1 = async(myFunction);
然后我会得到这个错误:
no instance of constructor "std::thread::thread" matches the argument list. argument types are: (std::string () const)
然后我在网上读到,由于它是 const,我需要通过引用调用它,但所有在线方法都不起作用,我不确定问题是否是因为函数是常量还是不是。 我尝试过的:
thread t0(&myClass::myFunction); auto f1 = async(&myClass::myFunction);
和
thread t0(&myFunction); auto f1 = async(&myFunction);
在此之后,我将有两个新错误,我找不到解决方案:
std::invoke: no matching overloaded function found.
和
Failed to specialize function template 'unknown-type std::invoke(_Callable &&,_Types &&...)'
我认为这是由于我对线程和期货的工作原理缺乏了解,但我正在努力寻找与此相关的文献。 基本上我真的不明白我违反了什么规则,如果我的方法存在根本缺陷,任何方向或提示都会很好。谢谢你的时间。
std::string myClass::myFunction() const noexcept
这不是一个函数。这是一个类方法。两者之间有根本的区别。
你不能简单地写
myFunction();
代码中的某个位置,而不是同一类的另一个方法,该方法使用this
为类的同一实例调用不同的方法。 在同一类的方法之外的任何地方,myFunction();
都不会编译,并且编译错误是相同的确切原因。std::thread
构造函数的第一个参数是一个函数,而不是一个类方法。它可以是一个类方法,我很快就会介绍。但是你的第一个错误是混淆函数的概念和类方法,你需要理解。
你可以myFunction()
做一个static
类函数,然后它像任何普通函数一样工作,然后像往常一样将其提供给std::thread
。另一种选择是使用包装函数构造std::thread
,该包装函数将您希望其方法调用的任何类传递给包装函数,包装函数使用它。"无论哪个类"可以this
:
void invoke_func(const myClass *ptr)
{
ptr->myFunction();
}
// ...
std::thread new_thread{ this };
另一种可用于调用类方法的更现代方法是传递一个附加参数,即指向要调用其方法的类实例的指针:
std::thread new_thread{ &myClass::myFunction, this };
myFunction()
方法在这里不接受任何参数作为参数,但是当std::thread
构造函数的第一个参数是类方法而不是函数时,第一个参数被视为指向其方法被调用的类实例的指针,其余参数像往常一样转发。
但是你需要自己弄清楚你尝试调用哪个类的实例,是this
,还是类的其他实例。
虽然你经常可以在类中编写foo()
来调用this->foo()
,但作为快捷方式,当你直接"命名"成员函数时,情况并非如此,这就是你在这里所做的,因为你实际上是将成员函数指针传递给std::thread
。
它可以工作,你只需要提供对象指针:
std::thread t0(myFunction, this);
如果您愿意,可以将指针传递给其他myClass
!