[英]Passing vector to a thread function in c++
我試圖運行一個多線程矩陣求和函數,以便每一行將匯總在不同的線程中。 我嘗試實現將向量傳遞到模板類中的cpp線程函數的所有變通辦法,但仍然遇到此常見錯誤。
對於代碼:
template <typename T> class Matrix
{
// variables for matrix size and variables in a one dimension vector
unsigned int _rows;
unsigned int _cols;
vector<vector<T> > _matrix;
// Matrix template class functions declarations (all common operators and constructors)
void sumLine(vector<T>& first, vector<T>& second, vector<T>& result);
Matrix<T> operator+(const Matrix<T> & other) const;
};
// Matrix template class functions implmentations
template <typename T> void Matrix<T>::sumLine(vector<T>& first, vector<T>& second, vector<T>& result)
{
for (unsigned int colIdx = 0; colIdx < _cols; colIdx++)
{
result[colIdx] = first[colIdx] + second[colIdx];
}
}
template <typename T> Matrix<T> Matrix<T>::operator+(const Matrix<T> & other) const
{
vector<thread> threads;
vector<vector<T> > results;
vector<T> newRow(_cols);
results.resize(_rows, newRow);
for (unsigned int rowIdx = 0; rowIdx < _rows; rowIdx++)
{
vector<T> first = _matrix[rowIdx];
vector<T> second = other._matrix[rowIdx];
vector<T> result = results[rowIdx];
threads.push_back(thread(Matrix<T>::sumLine, std::ref(first), std::ref(second), std::ref(result)));
}
for (unsigned int thrdIdx = 0; thrdIdx < _rows; thrdIdx++)
{
threads[thrdIdx].join();
}
// do something with vector<vector<T>> results
}
而且仍然用gcc編譯后,我得到:
In file included from /usr/lib/gcc/x86_64-pc-cygwin/4.9.3/include/c++/thread:39:0,
from Matrix.hpp:12,
from main.cpp:13:
/usr/lib/gcc/x86_64-pc-cygwin/4.9.3/include/c++/functional: In instantiation of 'struct std::_Bind_simple<std::_Mem_fn<void (Matrix<Complex>::*)(std::vector<Complex, std::allocator<Complex> >&, std::vector<Complex, std::allocator<Complex> >&, std::vector<Complex, std::allocator<Complex> >&)>(std::reference_wrapper<std::vector<Complex, std::allocator<Complex> > >, std::reference_wrapper<std::vector<Complex, std::allocator<Complex> > >, std::reference_wrapper<std::vector<Complex, std::allocator<Complex> > >)>':
/usr/lib/gcc/x86_64-pc-cygwin/4.9.3/include/c++/thread:137:47: required from 'std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (Matrix<Complex>::*)(std::vector<Complex, std::allocator<Complex> >&, std::vector<Complex, std::allocator<Complex> >&, std::vector<Complex, std::allocator<Complex> >&); _Args = {std::reference_wrapper<std::vector<Complex, std::allocator<Complex> > >, std::reference_wrapper<std::vector<Complex, std::allocator<Complex> > >, std::reference_wrapper<std::vector<Complex, std::allocator<Complex> > >}]'
Matrix.hpp:404:102: required from 'Matrix<T> Matrix<T>::operator+(const Matrix<T>&) const [with T = Complex]'
main.cpp:59:14: required from here
/usr/lib/gcc/x86_64-pc-cygwin/4.9.3/include/c++/functional:1665:61: error: no type named 'type' in 'class std::result_of<std::_Mem_fn<void (Matrix<Complex>::*)(std::vector<Complex, std::allocator<Complex> >&, std::vector<Complex, std::allocator<Complex> >&, std::vector<Complex, std::allocator<Complex> >&)>(std::reference_wrapper<std::vector<Complex, std::allocator<Complex> > >, std::reference_wrapper<std::vector<Complex, std::allocator<Complex> > >, std::reference_wrapper<std::vector<Complex, std::allocator<Complex> > >)>'
typedef typename result_of<_Callable(_Args...)>::type result_type;
^
/usr/lib/gcc/x86_64-pc-cygwin/4.9.3/include/c++/functional:1695:9: error: no type named 'type' in 'class std::result_of<std::_Mem_fn<void (Matrix<Complex>::*)(std::vector<Complex, std::allocator<Complex> >&, std::vector<Complex, std::allocator<Complex> >&, std::vector<Complex, std::allocator<Complex> >&)>(std::reference_wrapper<std::vector<Complex, std::allocator<Complex> > >, std::reference_wrapper<std::vector<Complex, std::allocator<Complex> > >, std::reference_wrapper<std::vector<Complex, std::allocator<Complex> > >)>'
_M_invoke(_Index_tuple<_Indices...>)
當Complex是一個復數類時,我為矩陣模板類編寫了代碼,而我的主要功能是嘗試使用此計算。 怎么了 如果它在復雜類中,是否有更簡單的方法將參數傳遞給線程函數來避免這種情況?
您應該發布Complex類,這可能是問題所在。
同樣在您的代碼中: vector<T> first = _matrix[rowIdx]; vector<T> second = other._matrix[rowIdx]; vector<T> result = results[rowIdx];
vector<T> first = _matrix[rowIdx]; vector<T> second = other._matrix[rowIdx]; vector<T> result = results[rowIdx];
您應該這樣寫: vector<T>& first = _matrix[rowIdx];
因為您正在復制這些向量...甚至const vector<T>& first = _matrix[rowIdx];
如果您不修改它們。
然后您可以刪除std :: ref
以下代碼編譯(使用clang 3.5),並避免將對臨時對象的引用傳遞給任何thread
。
#include <vector>
#include <thread>
#include <stdexcept>
using namespace std; // for expose only (don't do this in real code!!)
template <typename T> class Matrix
{
using row = vector<T>;
size_t _rows, _cols;
vector<row> _matrix;
Matrix(vector<row>&&); // defined elsewhere
row sumLine(row const& first, row const& second) const
{
row result; // don't tempt the compiler to default
result.reserve(_cols); // initialise result[i] for all columns
for(size_t c=0; c!=_cols; ++c)
result.emplace_back(first[c]+second[c]);
return result; // return is fast (no copy!)
}
Matrix<T> operator+ (const Matrix<T>& other) const;
};
template <typename T>
Matrix<T> Matrix<T>::operator+(const Matrix<T>&other) const
{
if(other._cols != _cols)
throw std::runtime_error("column number mismatch in Matrix+Matrix");
if(other._rows != _rows)
throw std::runtime_error("row number mismatch in Matrix+Matrix");
vector<thread> threads; threads.reserve(_rows);
vector<row> result(_rows);
for(size_t r=0; r!=_rows; ++r)
threads.emplace_back([&,r]() {
result[r] = Matrix<T>::sumLine(_matrix[r],other._matrix[r]);
});
for(size_t r=0; r!=_rows; ++r)
threads[r].join();
return move(result);
}
template class Matrix<double>;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.