如何在 C++ 中异步调用静态方法?
How to call a static method asynchronously in c++?
我想 运行 我的 minimax 算法异步,这样它就不会在等待转弯时冻结 ui。这是我需要调用的静态方法:
//ChessContext is the current state of the board
//Turn contains fromX, fromY, toX, toY when moving a piece
static Turn getBestTurn(ChessContext cc, int depth);
我试过这个:
//context is a reference to the game currently played
auto fu = std::async(std::launch::async, ChessContext::getBestTurn, context , 5);
Turn t = fu.get();
它给我一个错误说
boardview.cpp:69:23: error: no matching function for call to 'async'
future:1712:5: note: candidate template ignored: substitution failure [with _Fn = Turn (&)(ChessContext, int), _Args = <ChessContext &, int>]:
no type named 'type' in 'std::result_of<Turn ((ChessContext, int))(ChessContext, int)>'
future:1745:5: note: candidate template ignored: substitution failure [with _Fn = std::launch, _Args = <Turn (&)(ChessContext, int), ChessContext &, int>]:
no type named 'type' in 'std::result_of<std::launch (Turn ()(ChessContext, int), ChessContext, int)>'
我最终想 运行 算法在每次可能的情况下都打开一个单独的线程,或者一次打开两个线程,看看它是否能提高性能。
最小代码:
#include <iostream>
#include <thread>
#include <future>
class Turn
{
};
class ChessContext
{
public:
ChessContext();
ChessContext(ChessContext &cc);
static Turn getBestTurn(ChessContext cc, int depth);
};
int main(){
ChessContext context;
auto fu = std::async(std::launch::async, ChessContext::getBestTurn, context, 5);
}
您的最小示例可以正常编译。
你的 actual 代码还有这个:
ChessContext(ChessContext &cc);
这不是一个普通的拷贝构造函数。复制构造函数 usually 通过 const
引用获取参数。
这是一个重现您的问题的最小示例:
#include <future>
struct A {
A() {}
A(A&) {}
};
void test(A) {}
int main() {
A a;
test(a); // OK
std::async(std::launch::async, &test, a); // Not OK
}
这是因为 std::launch::async
复制参数,并且非常量引用不绑定到临时对象。
要修复,请将复制构造函数更改为
ChessContext(ChessContext const &cc);
您可以使用 lambda 让生活更轻松:
auto fu = std::async(std::launch::async, [&]() { ChessContext::getBestTurn(context , 5); });
至于多线程,minimax 的工作线程是可取的,但在实际场景中,由于您将需要哈希表和其他东西,以允许强制移动或撤消移动等,不建议为每个深度搜索单独线程.
ChessContext
不可复制。 ChessContext(ChessContext &cc)
不是拷贝构造函数,你需要 ChessContext(const ChessContext &cc)
.
我想 运行 我的 minimax 算法异步,这样它就不会在等待转弯时冻结 ui。这是我需要调用的静态方法:
//ChessContext is the current state of the board
//Turn contains fromX, fromY, toX, toY when moving a piece
static Turn getBestTurn(ChessContext cc, int depth);
我试过这个:
//context is a reference to the game currently played
auto fu = std::async(std::launch::async, ChessContext::getBestTurn, context , 5);
Turn t = fu.get();
它给我一个错误说
boardview.cpp:69:23: error: no matching function for call to 'async'
future:1712:5: note: candidate template ignored: substitution failure [with _Fn = Turn (&)(ChessContext, int), _Args = <ChessContext &, int>]:
no type named 'type' in 'std::result_of<Turn ((ChessContext, int))(ChessContext, int)>'
future:1745:5: note: candidate template ignored: substitution failure [with _Fn = std::launch, _Args = <Turn (&)(ChessContext, int), ChessContext &, int>]:
no type named 'type' in 'std::result_of<std::launch (Turn ()(ChessContext, int), ChessContext, int)>'
我最终想 运行 算法在每次可能的情况下都打开一个单独的线程,或者一次打开两个线程,看看它是否能提高性能。
最小代码:
#include <iostream>
#include <thread>
#include <future>
class Turn
{
};
class ChessContext
{
public:
ChessContext();
ChessContext(ChessContext &cc);
static Turn getBestTurn(ChessContext cc, int depth);
};
int main(){
ChessContext context;
auto fu = std::async(std::launch::async, ChessContext::getBestTurn, context, 5);
}
您的最小示例可以正常编译。
你的 actual 代码还有这个:
ChessContext(ChessContext &cc);
这不是一个普通的拷贝构造函数。复制构造函数 usually 通过 const
引用获取参数。
这是一个重现您的问题的最小示例:
#include <future>
struct A {
A() {}
A(A&) {}
};
void test(A) {}
int main() {
A a;
test(a); // OK
std::async(std::launch::async, &test, a); // Not OK
}
这是因为 std::launch::async
复制参数,并且非常量引用不绑定到临时对象。
要修复,请将复制构造函数更改为
ChessContext(ChessContext const &cc);
您可以使用 lambda 让生活更轻松:
auto fu = std::async(std::launch::async, [&]() { ChessContext::getBestTurn(context , 5); });
至于多线程,minimax 的工作线程是可取的,但在实际场景中,由于您将需要哈希表和其他东西,以允许强制移动或撤消移动等,不建议为每个深度搜索单独线程.
ChessContext
不可复制。 ChessContext(ChessContext &cc)
不是拷贝构造函数,你需要 ChessContext(const ChessContext &cc)
.