将 std::async 与接收 cv::OutputArray 的方法一起使用以分配它不起作用
Using std::async with a method receiving a cv::OutputArray in order to assign it doesn't work
我有以下功能:
void MyClass::myFunc(cv::OutputArray dst) const {
cv::Mat result;
...
dst.assign(result);
}
如果我运行这样:
cv::Mat result;
myFunc(result);
otherFunc(result);
它工作正常并且 otherFunc
收到 result
修改 myFunc
。
但是如果我这样使用 std::async
:
cv::Mat result;
auto resultFuture = std::async(&MyClass::myFunc, this, result);
resultFuture.wait();
otherFunc(result);
otherFunc
收到空 result
。我做错了什么?
根本原因 是通过引用 (&) 将参数通过 std::async
is problematic. You can read about it here: Passing arguments to std::async by reference fails 传递给 运行 的函数(在您的情况下没有编译错误,但 link 概括地解释了这个问题。
在您的情况下,您使用 cv::OutputArray
,它在 opencv 中定义为参考类型:
typedef const _OutputArray& OutputArray;
我假设您需要引用语义,因为您希望 result
对象由 myFunc
更新。
解决办法就是用std::ref
.
但是由于您传递的 result
对象是 cv::Mat
,因此 myFunc
将收到 cv::Mat&
.
更可取且更直接
我还设法使用 cv::OutputArray
生成了一个解决方案,但它需要一个丑陋的转换(除了 std::ref
)。它在 MSVC 上运行良好,但我不确定它是否普遍有效。
下面是演示这两个选项的代码。如果可以的话,我建议使用第一种方法。您可以在 result
初始化后打印尺寸的地方调用 otherFunc(result);
。
#include <opencv2/core/core.hpp>
#include <future>
#include <iostream>
// Test using a cv::Mat &:
class MyClass1
{
void myFunc(cv::Mat & dst) const
{
cv::Mat result(4, 3, CV_8UC1);
result = 1; // ... initialize some values
dst = result; // instead of using cv::OutputArray::assign
}
public:
void test()
{
cv::Mat result;
std::cout << "MyClass1: before: " << result.cols << " x " << result.rows << std::endl;
auto resultFuture = std::async(&MyClass1::myFunc, this, std::ref(result));
resultFuture.wait();
// Here result will be properly set.
std::cout << "MyClass1: after: " << result.cols << " x " << result.rows << std::endl;
}
};
// Test using a cv::OutputArray:
class MyClass2
{
void myFunc(cv::OutputArray dst) const
{
cv::Mat result(4, 3, CV_8UC1);
result = 1; // ... initialize some values
dst.assign(result);
}
public:
void test()
{
cv::Mat result;
std::cout << "MyClass2: before: " << result.cols << " x " << result.rows << std::endl;
auto resultFuture = std::async(&MyClass2::myFunc, this, std::ref(static_cast<cv::OutputArray>(result)));
resultFuture.wait();
// Here result will be properly set.
std::cout << "MyClass2: after: " << result.cols << " x " << result.rows << std::endl;
}
};
int main()
{
// Test receiving a cv::Mat&:
MyClass1 m1;
m1.test();
// Test receiving a cv::OutputArray:
MyClass2 m2;
m2.test();
return 0;
}
我有以下功能:
void MyClass::myFunc(cv::OutputArray dst) const {
cv::Mat result;
...
dst.assign(result);
}
如果我运行这样:
cv::Mat result;
myFunc(result);
otherFunc(result);
它工作正常并且 otherFunc
收到 result
修改 myFunc
。
但是如果我这样使用 std::async
:
cv::Mat result;
auto resultFuture = std::async(&MyClass::myFunc, this, result);
resultFuture.wait();
otherFunc(result);
otherFunc
收到空 result
。我做错了什么?
根本原因 是通过引用 (&) 将参数通过 std::async
is problematic. You can read about it here: Passing arguments to std::async by reference fails 传递给 运行 的函数(在您的情况下没有编译错误,但 link 概括地解释了这个问题。
在您的情况下,您使用 cv::OutputArray
,它在 opencv 中定义为参考类型:
typedef const _OutputArray& OutputArray;
我假设您需要引用语义,因为您希望 result
对象由 myFunc
更新。
解决办法就是用std::ref
.
但是由于您传递的 result
对象是 cv::Mat
,因此 myFunc
将收到 cv::Mat&
.
更可取且更直接
我还设法使用 cv::OutputArray
生成了一个解决方案,但它需要一个丑陋的转换(除了 std::ref
)。它在 MSVC 上运行良好,但我不确定它是否普遍有效。
下面是演示这两个选项的代码。如果可以的话,我建议使用第一种方法。您可以在 result
初始化后打印尺寸的地方调用 otherFunc(result);
。
#include <opencv2/core/core.hpp>
#include <future>
#include <iostream>
// Test using a cv::Mat &:
class MyClass1
{
void myFunc(cv::Mat & dst) const
{
cv::Mat result(4, 3, CV_8UC1);
result = 1; // ... initialize some values
dst = result; // instead of using cv::OutputArray::assign
}
public:
void test()
{
cv::Mat result;
std::cout << "MyClass1: before: " << result.cols << " x " << result.rows << std::endl;
auto resultFuture = std::async(&MyClass1::myFunc, this, std::ref(result));
resultFuture.wait();
// Here result will be properly set.
std::cout << "MyClass1: after: " << result.cols << " x " << result.rows << std::endl;
}
};
// Test using a cv::OutputArray:
class MyClass2
{
void myFunc(cv::OutputArray dst) const
{
cv::Mat result(4, 3, CV_8UC1);
result = 1; // ... initialize some values
dst.assign(result);
}
public:
void test()
{
cv::Mat result;
std::cout << "MyClass2: before: " << result.cols << " x " << result.rows << std::endl;
auto resultFuture = std::async(&MyClass2::myFunc, this, std::ref(static_cast<cv::OutputArray>(result)));
resultFuture.wait();
// Here result will be properly set.
std::cout << "MyClass2: after: " << result.cols << " x " << result.rows << std::endl;
}
};
int main()
{
// Test receiving a cv::Mat&:
MyClass1 m1;
m1.test();
// Test receiving a cv::OutputArray:
MyClass2 m2;
m2.test();
return 0;
}