问题
I have implemented a Matrix class with a move assignment as
template <typename OutType>
class Matrix
{
public:
int Rows_; // number of Rows
int Columns_; // number of Columns
OutType *data_; // row Major order allocation
// STUFF
Matrix<OutType> & operator=(Matrix<float>&& other) {
swap(other);
return *this;
}
void swap(Matrix<float>& other) {
int t_Rows_ = Rows_; Rows_ = other.Rows_; other.Rows_ = t_Rows_;
int t_Columns_ = Columns_; Columns_ = other.Columns_; other.Columns_ = t_Columns_;
float* t_ptr = data_;
data_ = other.data_;
other.data_ = t_ptr; }
}
in order to implement the B=f(A);
syntax, as suggested in
C++: Implementing B=f(A), with B and A arrays and B already defined
As possible function, I'm considering the FFT, implemented as
Matrix<float> FFT(const Matrix<float> &in)
{
Matrix<float> out(in.GetRows(),in.GetColumns());
// STUFF
return out;
}
Is there any room for further efficiency improvements? Is there any further trick to improve, for example, the move assignment or the swap
function?
EDIT: NEW SOLUTION FOLLOWING KONRAD RUDOLPH'S COMMENT
Matrix & operator=(Matrix&& other) {
std::swap(Rows_, other.Rows_);
std::swap(Columns_, other.Columns_);
std::swap(data_, other.data_);
std::cout << "move assigned \n";
return *this;
}
回答1:
I recommend implementing move-assignment and move-construction for your class:
Matrix( Matrix<OutType> &&that ) noexcept
: Rows_(that.Rows_)
, Cols_(that.Cols_)
, data_(that.data_)
{
that.Rows_ = that.Cols_ = 0;
that.data_ = nullptr;
}
Matrix<OutType> &operator=( Matrix<OutType> &&that ) noexcept {
using std::swap;
swap( Rows_, that.Rows_ );
swap( Cols_, that.Cols_ );
swap( data_, that.data_ );
return *this;
}
If you implement move operations (construction and assignment) like this, std::swap
should work great for your code, and you don't need to provide your own. If you do want to provide your own implementation of swap
, I recommend providing it as a two-argument friend
function so that it can be found through Argument Dependent Look-up. I also recommend calling swap
(and all other functions) without namespace qualifications, as shown above, so that ADL is not suppressed (unless, for some reason, you really need to specify exactly which function is called, and an overload customized for the specific type would be wrong). ADL is especially valuable when dealing with templated code. If you call std::swap
with the std::
qualifier, you significantly reduce the opportunity for user-defined types to provide a more efficient swap implementation.
来源:https://stackoverflow.com/questions/16287644/implementing-the-b-fa-syntax-by-move-assignment