How can an object find that is rvalue reference(unnamed value) in C++?

63 Views Asked by At

I have a class named Matrix. I want overload operator ! that return transpose of matrix. When the main matrix is a unnamed object I prefer to use it's allocated memory to construct transpose matrix, otherwise use new matrix. How can I do this.(We assume that the number of rows and columns of the matrix is ​​equal)

class Matrix {
// ...
/* transpose of a unnamed matrix */
Matrix&& operator !() 
{
    for (int i = 0; i < rows_; ++i)
        for (int j = 0; j < cols_; ++j)
            std::swap(data[i][j],data[j][i]);
    return std::move(*this);
}

/* transpose of a matrix that is not rvalue refrence */
Matrix operator !()const
{
        Matrix ret(cols_, rows_);
    
        for (int i = 0; i < rows_; ++i)
            for (int j = 0; j < cols_; ++j)
                ret.data[j][i] = data[i][j];
        return temp;
}
};

The compiler does not allow me to have both overload together.

1

There are 1 best solutions below

2
Artyer On

You can do this with ref-qualifiers:

// (Also I would recommend you return by value here to prevent dangling references. You can still move from *this.)
Matrix&& operator !() && {  // Called on rvalues
    // ...
}
Matrix operator !() const& {  // Called on lvalues (and const rvalues)
    // ...
}

You could also write it as a free function:

// (Or have these outside the class)
friend Matrix&& operator!(Matrix&& mat) {
    // ...
}
friend Matrix operator!(const Matrix& mat) {
    // ...
}

// You can also take by value instead so the move or copy is at the call site
friend Matrix operator!(Matrix mat) {
    // ... (in place transpose mat)
}

And as people have pointed out in the comments, !x usually means !static_cast<bool>(x), and under the principle of least surprise, you should probably not make it do something different.

Consider operator~, or a friend function T (T(mat) looks pretty self explanatory)